Everything your agent reads can give it orders

Most teams test prompt injection by typing “ignore your previous instructions” into the chat window and checking that the agent refuses. It is a reasonable first test, and it targets the least likely attacker. The person at the keyboard already has access; they have little to gain by tricking the agent into using it.
The attacker who matters is whoever wrote the text the agent was asked to process: the inbound email, the supplier’s PDF, the support ticket, the web page in the search results. Everything an agent reads is somebody’s input, and each of those somebodies gets a voice in the same channel as your instructions. The OWASP Top 10 for LLM Applications describes this indirect form explicitly, alongside the direct one, and it is the form that reaches production.
The read surface is larger than anyone listed
Every external source is someone else’s text. Inbound mail, tickets, uploaded documents, search results, CRM notes typed by customers, file names, calendar invitations. If a stranger can put words into it, a stranger can address your agent through it.
Hidden text is still text. White-on-white paragraphs, image alt text, document metadata, comments in a spreadsheet. The person who reviewed the document never saw them; the model reads them with the same weight as everything else.
Tool results count. A record field filled in by a customer is untrusted even though your own code fetched it. Who made the call does not matter. Who wrote the content does.
Other agents count too. In a multi-agent system, the summary a research sub-agent returns after reading a web page is that web page, paraphrased. Passing through another model does not make text more trustworthy; it only makes its origin harder to see.
Three ingredients, and you remove one
Injection turns into an incident when three things meet in one context: untrusted content, access to something worth taking or changing, and a way to act on the outside world — send, post, fetch a URL, write somewhere other people read. Any two are manageable. All three together are an exfiltration path waiting for someone to write the instructions.
Detecting injected instructions is worth doing, and it is probabilistic: filters and classifiers lower the success rate without closing the door. The reliable design move is structural. Make sure no single context holds all three.
Infographic
Where injection turns into an incident
Can act outwardNo outbound path
Trusted input onlyUntrusted input
Designing so no context holds all three
Separate reading from acting. One component reads the untrusted material and returns only structured fields — a category, an amount, an order number — validated against a schema. The component that plans and calls tools never sees the raw text. Free text that has to pass through travels as a quoted value and is never read again as instructions.
Taint the session. Once untrusted content enters a context, the orchestrator marks the session, and from then on outbound tools are either unavailable or require approval. That is a rule in code. It does not depend on the model noticing anything.
Close the quiet channels. Exfiltration rarely looks like an email to the attacker. It looks like a rendered image whose address carries data in the query string, a helpful link the user is invited to click, a fetch to a URL assembled from private data, a comment on a public ticket. Outbound fetches go through an allowlist, agent output does not render remote images, and links point only at domains you know.
Show approvers the effect, not the story. When a manipulated agent asks for approval, the explanation it writes was produced under the attacker’s influence too. The approver should see the exact recipient, amount and payload, rendered by code from the tool call itself, rather than the agent’s account of why it is fine.
Test the read surface, not the chat box
Plant instructions where a real attacker would: in a test email, a PDF, a ticket field, a page on a site the agent is allowed to browse. Then check what the agent did, not what it said. Keep those cases in the evaluation set, so a model upgrade or a prompt change that reopens a hole fails in testing rather than in the incident log.
The honest position
No model available today reliably separates instructions from data, and planning as if the next one will is a bet nobody should place with a customer’s data. What can be designed is the outcome when it fails: what the agent had within reach, and where it could have sent it.
That map — what the agent reads, what it can reach, where it can send — is the first thing we draw in an AI agents engineering engagement, before anybody chooses a model.
- AI agents
- prompt injection
- data exfiltration
- architecture