RAG poisoning
Indirect prompt injection via poisoned documents in a retrieval-augmented (RAG) corpus.
Static. Builds its prompts up front and sends them. It drives no model of its own, so it is cheap and repeatable.
Poison the retrieved corpus and judge what the target does with it.
Helper models
Models this attack drives, configured under its roles. Each one is a ModelConfig.
| Role | Kind | Needed | What it does |
|---|---|---|---|
attacker | chat model | required | Writes the poisoned passages that are planted in the retrieved documents. |
embedder | embedding model | required | Embedding model used to index the documents and retrieve the passages most relevant to each query. |
Parameters
Settings for the algorithm itself, written under the attack's parameters. Anything left out keeps its default.
| Field | Type | Default | Description |
|---|---|---|---|
documents | list of string (at least 1) | required | The knowledge base to poison, one entry per document (raw text). |
benign_queries | list of string | empty | Benign queries to retrieve with. Empty means the attacker writes them. |
queries_per_goal | integer (>= 1) | 5 | Queries generated per goal when none are given. |
strategy | string | inline_context_override | How the payload is written: inline_context_override | append_hidden_directive | maximize_retrieval. |
poisoned_ratio | number (> 0.0, <= 1.0) | 0.5 | Fraction of the corpus to poison, most-relevant documents first. |
payloads_per_query | integer (>= 1) | 5 | Payloads inserted per query anchor, each at its own paragraph. |
chunk_size | integer (>= 1) | 1000 | Retrieval chunking. |
chunk_overlap | integer (>= 0) | 200 | Characters shared between consecutive chunks, so a passage cut at a chunk boundary is still retrievable. |
top_k | integer (>= 1) | 5 | Chunks retrieved per query. |
vulnerable_prompt | boolean | false | Treat instructions in retrieved context as authoritative. The attack's ceiling, not a realistic defence. |
In a campaign file
attacks:
- name: rag
parameters:
documents:
- '...'
roles:
attacker:
name: llama3.2
connection:
provider: ollama
type: OLLAMA
embedder:
name: nomic-embed-text
connection:
provider: ollama
type: OLLAMA
Needs a helper model
This attack cannot run without attacker, embedder. A campaign that leaves it out fails to resolve, before anything is attacked.