
Prompt injection has been the top item in every edition of the OWASP Top 10 for LLM Applications, and the 2026 edition says plainly that there is no reliable prevention. The reason is structural. A language model receives instructions and data in the same channel, the context window, and has no equivalent of the parameterised query that separated code from data in databases. Anything the model reads, whether a web page, an email, a tool result, a calendar invite or a résumé, can carry instructions, and the model has no principled way to know which instructions carry authority.
Why filtering cannot be the boundary
Every filtering defence works by lowering probability. Classifiers trained on known injection patterns catch known patterns; instruction hierarchy training teaches the model to prefer privileged instructions most of the time; delimiters and spotlighting make the model less likely to confuse data with commands. All of these are worth having. None of them is a boundary, and the evidence is now overwhelming. In 2025 a team from OpenAI, Anthropic and Google DeepMind evaluated twelve published defences that had reported near-zero attack success and bypassed most of them with success rates above 90 percent, simply by adapting the attack to the defence and spending effort on optimisation. EchoLeak defeated Microsoft's injection classifier by phrasing the payload as instructions to the human reader. The Salesforce ForcedLeak chain exfiltrated data through an image request to a domain that an allowlist trusted because its registration had lapsed. In each case the defenders had layers; the attacker moved second.
The practical rule that follows is uncomfortable but clarifying: assume the model will be fooled. Design for the day when an attacker's instruction reaches the model and is followed, and ask what the model can do at that moment.
The lethal trifecta
Simon Willison's formulation has become the field's pre-deployment check. An agent is dangerous when it combines three things: access to private data, exposure to untrusted content, and a way to communicate externally. Remove any one leg and the worst outcome changes. An agent that reads untrusted web pages but holds no private data cannot leak much. An agent with private data that reads only trusted input cannot be hijacked by content. An agent with both but no outbound channel can be manipulated but cannot exfiltrate. Most real incidents are trifecta cases: the GitHub MCP toxic agent flow (private repositories, a public issue, a public pull request), the Comet calendar injection (local files, an attacker-authored invite, the browser's network access), EchoLeak (mailbox contents, an inbound email, a rendered image URL).
The trifecta is a design tool because it is measurable. For every agent, list the data it can read, the sources that can write into its context, and the sinks its output reaches. If all three columns are populated, you have a decision to make: split the agent, gate one of the columns, or accept the risk with compensating controls and monitoring.
Separating control from data
The strongest published defence, CaMeL from Google DeepMind, borrows from operating system security rather than from machine learning. A privileged model reads only the trusted request and writes a plan, a small program in a restricted language, that says which tools will run and how their results connect. A quarantined model, with no tool access, reads untrusted content and returns typed values. An interpreter executes the plan, attaches a capability to every value recording its provenance, and checks a policy before each tool call: data that came from an untrusted email cannot be sent to an address that did not come from the user. Because untrusted text never controls execution, the security property holds no matter how persuasive the injection is. On the AgentDojo benchmark the design reduced attack success to near zero at a measurable cost in tasks completed.
You do not need to implement CaMeL to benefit from its principle. The dual-model pattern is reproducible in any orchestration layer: keep planning and tool selection in a component that never sees untrusted content, and make everything that reads untrusted content return data through a schema rather than through free text. The retailer case study in this knowledge base is a production example: the refund tool can only receive an account identifier that came from the authenticated session, so a product review that says refund to this account has nowhere to go.
Bounding the blast radius
Where separation is not practical, bound what a hijacked model can reach. The controls are familiar to any security engineer and are exactly the ones that the incident record shows to be missing.
- Least privilege per task. Agents should hold credentials scoped to the task, issued just in time and revoked on completion. A token that covers every repository turns a planted issue into a leak of private code; a token scoped to one repository does not.
- Human approval for consequential actions, bound to parameters. Approval must cover what will be done, not only the goal, and the agent must not be able to satisfy it itself. Deleting a database, sending money, publishing code and modifying access all qualify.
- Output validation at every sink. Model output that flows into HTML, SQL, shell commands, email or a rendering layer must be validated against a schema first. Improper output handling dropped in the 2026 OWASP ranking because it is fixable; fix it.
- Egress control. Rendered images, link previews and outbound HTTP are exfiltration channels. Allowlist destinations, audit the allowlist for expired domains, and do not let retrieved content decide what the assistant renders.
- Session and tenant boundaries in retrieval. Enforce document-level authorisation before similarity ranking, not after. Slack AI and several RAG incidents collapsed access boundaries because retrieval ignored them.
Reducing probability, honestly
The probability-lowering layers still earn their place, provided nobody mistakes them for the boundary. Use a model with instruction hierarchy training. Run an injection classifier on inputs and tool results and treat hits as signals for logging and rate limiting, not as the only defence. Mark data boundaries with spotlighting or delimiters. Keep hidden context free of secrets, because the 2026 OWASP list is right that system prompts and tool descriptions will be exposed. Monitor reasoning and actions with a separate model that was not trained against the monitor, and set it to halt sessions that cross declared scope.
Testing that means something
Test against the attacks that work, not the ones that are convenient. AgentDojo gives a dual score, task completion and injection success, so you can see the utility cost of each control. promptfoo and DeepTeam let you encode the trifecta and the OWASP categories as regression tests that run on every change. Then hire or become the adaptive attacker: give a red team the design documents and ask them to reach the sink. If the design is sound, they will find the model can be fooled and that it does not matter; if it is not, you will learn where the boundary really is before an attacker does.
Summary
Prompt injection is not going away and the model is not going to stop being fooled. Security comes from what the model can reach when it is: a planner that never sees untrusted content, typed data instead of free text, capabilities that follow provenance, least privilege, approval gates, validated outputs and controlled egress. Everything else is a probability adjustment, useful and insufficient.



