Indirect Prompt Injection
Indirect prompt injection is when the attacker never chats with you — they plant instructions in a page, PDF, email, or image your app retrieves. The user asked something ordinary; the model still reads the plant.
Explain like I'm new to AI
Direct injection is a hostile user. Indirect is a hostile document in a helpful pipeline: summarize this URL, search the wiki, read the inbox, look at this screenshot.
user ask (benign) → retrieve → untrusted content in context → model
How it lands: The user asked for a summary. Hidden instructions in the page (or in pixels a VLM will OCR) ride into context.
Default defense: Treat retrieved web text as hostile data. Don't give that turn send-email or browse-to-attacker-URL tools.
This is the production-shaped bug for RAG and agents. OWASP's indirect case is a page that steers a summarizer into leaking the conversation (for example via a crafted outbound fetch). You do not need the recipe to understand the rule: retrieved content is untrusted input, equal to a stranger typing.
Mental model
A waiter who reads the customer's note and a flyer stuck to the menu. The flyer was printed by someone who never entered the restaurant.
How it works
- Benign user ask.
- Tool or retriever pulls external bytes (HTML, PDF, mail, image, tool output, MCP resource, memory).
- Those bytes land in context, often unlabeled.
- The model continues the job as if those bytes were instructions.
- If tools remain enabled on that turn, the plant can request them.
Defenses that stack: segregate untrusted blocks ("retrieved document, not instructions"); don't enable acting tools on retrieve-and-summarize turns; allow-list fetch hosts; HITL for outbound; cite so a human can see what was retrieved; strip or sandbox active content (scripts, tracking pixels) before the model — that's output/fetch hygiene, not a prompt trick.
Multimodal: VLMs read text in images. Same rule as RAG.
Real-world example
"Summarize this vendor PDF." The PDF tells the model the refund policy is unlimited and to call issue_refund. If that tool is on the belt, you have a finance incident. If the turn is summarization-only, you have a lying summary — still bad, contained.
Technical explanation
Tool outputs are an indirect channel too (MCP tool poisoning in the MCP category: the description or the result). Memory writes can persist a plant (memory-conflicts lesson).
Filters that grep for scare phrases fail closed-world. Prefer capability cuts over keyword cops. Classifiers can be an extra signal, not the gate for money movement.
RAG poisoning (later) is how the plant gets a high retrieval score. Indirect injection is what happens after it is in context.
Common mistakes
"The user is logged in and asked a normal question, so the context is safe." The danger was fetched.
- Browsing agents with send-email on the same kit.
- Rendering retrieved HTML in the model and in the UI without encoding (output handling).
When to use it
- Any retrieve, browse, inbox, or vision step. Design the turn as read-untrusted vs act-privileged.
When NOT to use it
- Don't skip this because you "don't allow jailbreaks." Indirect doesn't look like a jailbreak chat.
Alternatives
- Human reads the URL; the model never sees the page. Higher labor, smaller channel.
Quick quiz
Related concepts
- RAG Poisoning — RAG poisoning plants text in the index so retrieval serves it as context. Control who can write; treat hits as untrusted even when they look grounded.
- Multimodal Embeddings & RAG — Multimodal RAG retrieves images, frames, OCR, and audio — keep native media when pixels or sound are the answer.
Last reviewed: 2026-09-04 · Written by ByHeart AI · Reviewed by ByHeart AI