Prompt InjectionPart 6 of 8 · Contents
Indirect prompt injection
Indirect injection plants the instruction in content the model retrieves for a user, such as a document or email. An innocent question then triggers it. The attacker never joins the conversation.
Turning injection against other people
With direct injection, the attacker types the instruction into their own session. It can still reach other users' data or company systems, because the application exposes data and tools to the model. But the attacker has to be in the conversation. Indirect injection removes that limit.
You move the instruction into content the Draftly copilot reads for someone else. The copilot summarises any document shared into Priya's workspace. That includes a document an outside partner dropped in. You can leave your instruction inside one of those documents.
The attack waits for a routine request. A real colleague, who is not the attacker, asks the copilot to work with the shared document. The copilot retrieves it and reads every sentence in the same way. It has no way to tell the partner's planted sentence from the rest of the brief. So a sentence shaped like an instruction can steer the answer the colleague receives.
The victim did nothing wrong. The attacker was never in the conversation.
This is indirect prompt injection. The same move drives real incidents. ForcedLeak hid instructions in a Salesforce lead field. CamoLeak hid them in a pull request.
EscalationThe damage depends on what the copilot can do. If it can only write a summary, a planted note can distort that summary. If it also has a send tool, a planted note can become an unauthorised message or commitment under the workspace's own identity. The technique is identical. Only the model's reach changed.
Why the retrieved text runs as instructions
Chat formats include role markers that separate system messages from user messages. Providers train models to rank system instructions over user instructions. They also train them to rank both over the text inside documents. This trained ranking is called the instruction hierarchy.
For example, a system instruction should override a conflicting instruction in a retrieved document. No parser or permission check enforces that ranking. The model usually follows it. It can also fail.
A retrieved document carries no provenance tag. Nothing marks which sentence came from a trusted colleague and which came from an outside partner. When a document contains a sentence shaped like an order, the model can still follow it.
Two things decide whether a planted instruction fires.
Text that reads as a task for the assistant has more influence than text written for a human reader. The model is trained to act on instructions aimed at it. A defender can flag document lines that address the assistant as a detection signal.
The trigger matters as much as the payload. Ask the model to produce work from the document, such as summarise, review or triage. Producing work is when it tends to follow the document's instructions. Ask it only to relay the document, such as quote or display. Relaying usually just prints the planted text.
Turning a summary into a fetch
Picture the Draftly copilot working on a shared deal-desk brief. This is the Helios pilot brief, which an outside partner can edit. The document does not need to contain the secret. It needs to tell the copilot to go and fetch one.
This turns the copilot's own access against its user. The copilot can read confidential records that the partner cannot. A planted note can ask it to use that access as part of the job. When a user asks for work on the document, the copilot may treat the note as one more step of that work.
The partner never touches the confidential record. The copilot does the fetching with its own permissions. This pattern is called a confused deputy: a trusted component misled into using its authority for someone else.
A defender breaks the chain in two places. Retrieved text should not be able to trigger tool calls on its own. Data the copilot fetches should be justified by what the user asked for.
The signal to look forOutput that contains data the user never asked for, and that the document never held, is the tell. Text an outside party controlled crossed a trust boundary. It made the copilot pull data on that party's behalf.
Blind exfiltration through what the client renders
Sometimes the reply never comes back to you. Brightloom Triage runs over an inbound message, such as a support email or a ticket. Its summary goes to the ops queue. The sender never sees it.
You can plant an instruction, but you will never see the answer. An instruction that tells the model to reveal something to the reader is useless, because you are not the reader. This is the blind case.
Here the attacker stops trying to read the answer. Instead, the attacker makes the answer call home.
The carrier is Markdown image syntax. It tells the client to load an image from a URL. Most chat surfaces auto-render these images. If the model's output includes an image whose URL the attacker controls, the victim's client requests that URL when the reply is displayed. Any data written into the URL travels with the request.
You never read the summary. You read your own server log.
This is the out-of-band channel. The data leaves through a side effect of rendering. The answer text itself stays clean. A tiny or broken image can leave nothing visible on screen.
CamoLeak used this against GitHub Copilot Chat. ShadowLeak did it zero-click against ChatGPT's research agent.
The signal to look forRequests from your users' clients to hosts you do not recognise are the tell. Check model output for image or link URLs that point outside an allowlist. An ordinary-looking summary can still carry one.
Close the render pathRender images in model output only from an allowlist of hosts, or proxy them. Keep the prompt-injection cheat sheet open for the pattern. Browse the incident database to see indirect injection and out-of-band exfiltration in shipped products.
Stuck in a lab? Each one has hints.
The payload is not typed into the chat. It hides in content the model retrieves, such as documents, articles, support notes, web pages and emails.
The attacker never touches the conversation. An ordinary user's ordinary question delivers the payload. The attack scales remotely and can be zero-click.
The tell is unrequested action. Watch for tool calls or output the user never asked for. Watch for behaviour that changes only when a specific source is loaded.
Defend the ingestion path, not the chat box. Wrap retrieved content as non-authoritative data. Provenance-check your sources. Limit the tools that can act on fetched content.
- Superhuman AI: One Email Made the Assistant Send Other Emails to an Attacker's Google Form
- AgentFlayer: A Poisoned Document Made ChatGPT Search Google Drive for API Keys
- CamoLeak: Silent Private-Repo Theft via GitHub Copilot Chat
- ForcedLeak: Draining CRM Data from Salesforce Agentforce
- ShadowLeak: Zero-Click, Server-Side Theft from ChatGPT Deep Research
- Morris II: The First Zero-Click Worm for GenAI Assistants
What is indirect prompt injection?
Indirect prompt injection hides the instruction in content the model reads for someone else. That content can be a shared document, a web page, an email or a support ticket. A normal user triggers it by asking the model to work with that content. The model then acts with the application's authority. The victim did nothing wrong, and the attacker was never in the conversation.
Why is indirect prompt injection more dangerous than direct injection?
Both can reach company systems or other users' data when the application gives the model access. Indirect injection adds a third-party route through content another user asks the model to read. The model may then use the application's tools or credentials to leak data or take unauthorised actions under someone else's identity.
What makes an indirect injection fire, summarising or quoting?
The kind of request matters. When the model produces work from a document, such as a summary, review or triage, it tends to treat embedded instructions as part of the job. When it only relays the document, such as a quote or display, it usually prints the planted text back. Text written as a task for the assistant is more influential than text written for a human. Defenders should test both kinds of request against every ingestion path.
How do attackers steal data when they never see the model's reply?
A planted formatting instruction tells the model to emit a Markdown image whose URL the attacker controls, with data written into the URL. Most chat surfaces auto-render the image. The victim's own client then fetches the URL, and the data lands in the attacker's log. The answer channel stays clean, because the data leaves through a side effect of rendering. CamoLeak and ShadowLeak used this out-of-band channel against shipped products.
© 2026 GenAI Security Lab. All rights reserved. You may read, quote, and link to this material with attribution. Copying, republishing, redistribution, resale, or use to train models or build competing products is prohibited without prior written permission.