Guides › Secure RAG › Indirect prompt injection
Indirect Prompt Injection in RAG Pipelines
Indirect prompt injection places attacker instructions inside content the model will retrieve, so the model reads them as part of its context and acts on them. The attacker never touches the victim's prompt. RAG is the main delivery channel, because inserting third-party text into a trusted context is precisely what RAG is for.
How is it different from prompt injection?
Direct prompt injection is a user typing adversarial instructions into the chat box, affecting their own session. Indirect injection puts those instructions into content the system retrieves later, so a different user triggers them without knowing. The attacker and the victim are different people, and the payload waits.
Greshake and colleagues described the class in Not what you've signed up for in 2023, showing that content pulled in at inference time can hijack an application without the attacker touching the user's input. OWASP lists Prompt Injection as LLM01 in its 2025 Top 10 for LLM Applications, its highest-ranked entry.
Where does the injected content come from?
Any repository users can write to that also feeds your index. A ticketing system where customers file issues. A wiki open to contractors. A shared mailbox. A CRM notes field. A vendor PDF.
In many deployments that set includes people outside the organization. If a vendor can file a support ticket and tickets are indexed, that vendor can write to your model's context.
What can an injection actually do?
It depends on what the assistant is allowed to do. Tool access is the difference between a manipulated answer and an exfiltration path.
Why do classifiers not solve it?
Prompt-injection classifiers score text against learned patterns of adversarial phrasing. They catch obvious attempts and raise the cost of casual ones, which is worth something.
That asymmetry does not close with a better model, because the classifier is trying to separate instruction from information in text where the distinction is genuinely ambiguous. Run one as a layer in a stack that assumes some fraction gets through.
What mitigations actually hold?
Structural separation first. Retrieved content should be marked as data, kept syntactically distinct from instructions, and treated as untrusted for the life of the request. This does not make the model immune, and it removes the easiest attacks.
Then authorization. Tool calls that a retrieved document appears to have triggered deserve a different authorization path than tool calls the user requested. If the model wants to call an outbound connector immediately after reading an untrusted document, that is the moment for a confirmation step rather than a log entry.
Then provenance. Log which chunks entered the context for which response, so that when something goes wrong you can identify the document that caused it. Without that record, an injection incident is unattributable.
And narrow the corpus. Content from sources that arbitrary external parties can write to deserves separate treatment from content authored internally. Indexing everything and defending at the model is the harder version of the problem.
How does this relate to poisoning?
They overlap at the edges. Injection targets one response by placing instructions in retrieved content. Data poisoning targets the system's behaviour by corrupting what it learns from or retrieves. Content injected into a retrieval corpus that persists and shapes many answers behaves like poisoning, which is why NIST's 2025 adversarial ML taxonomy keeps the categories distinct but adjacent.
Frequently asked questions
Can we detect injection attempts in our corpus?
Partially, and scanning at ingestion is worth doing because it is cheap and catches the unsophisticated cases. Treat it as filtering rather than prevention. Hidden text in metadata and alt attributes is the specific thing to check for, since it is invisible to a human reviewing the document.
Does a system prompt telling the model to ignore instructions in documents work?
Not reliably. It helps against naive payloads and is trivially bypassed by ones written to expect it. Instructions to a model are a preference, not a boundary. Anything you need to be a boundary belongs outside the model.
Is this a problem if our assistant is read-only?
Smaller, but not absent. A read-only assistant can still be made to produce a misleading answer, and if people act on those answers the consequence is real. It also tends not to stay read-only, because tool access is usually the next feature request.
Does indirect injection get more dangerous with agents?
Substantially. Every tool an agent holds is a capability an injected instruction can attempt to invoke. Assess the risk against what the agent can do, not against how likely an injection is, because the second question is not one you can answer confidently.
