
The two platforms I’ve written about so far both give an agent real power: access to private code, credentials, knowledge bases, and the ability to act on what it finds. That power is exactly what makes a specific class of attack so dangerous — one that doesn’t require finding a bug in your code at all. It’s called the lethal trifecta, a term coined by Simon Willison in mid-2025, and once you see it you can’t stop noticing it in almost every agent architecture.
The three ingredients
The trifecta is three capabilities that, individually, are completely reasonable things to want in an agent. The danger only appears when all three exist in the same system:
- Access to private data — the agent can read source code, internal documents, credentials, customer records, or a database.
- Exposure to untrusted content — the agent processes text it didn’t originate: a web page, an email, a file, a PR description, a support ticket. Anything an outside party could have written.
- The ability to communicate externally — the agent can make a web request, send an email, open a PR, post to an API — any channel that gets data out of its environment.
Remove any one of the three and the attack collapses. An agent that can read private data and talk to the outside world, but never processes untrusted content, is safe. An agent that processes untrusted content and can act on it, but has no access to anything sensitive, has nothing worth stealing. The trifecta is only lethal when all three are present at once.
How the attack actually runs
Walking through the flow in the diagram above: it starts with a malicious instruction hidden somewhere innocuous — a script tag in a web page, a comment in a file, a line buried in a support ticket — worded so it reads as an instruction rather than content. Someone asks the agent to do something ordinary, like “summarize this page,” and the agent ingests the poisoned content along with everything else.
From there, the model can’t reliably tell the difference between “the user’s instruction” and “text that happens to contain instruction-shaped sentences.” That’s the actual root cause — not a missing input filter, but the fact that current LLMs process instructions and data in the same channel. Once the model treats the injected text as a legitimate instruction, it uses whatever credentials and tools it already has: malicious action 1 is data access — using its normal, legitimate permissions to fetch something it was never supposed to touch, like database passwords. Malicious action 2 is exfiltration — using its normal, legitimate communication tools to send that data somewhere the attacker controls. Neither step requires the attacker to break anything. The agent is doing exactly what it was built to do, just on behalf of the wrong principal.
Why this is different from a normal vulnerability
A SQL injection or an RCE is a bug — you patch it and it’s gone. The lethal trifecta isn’t a bug in this sense; it’s an emergent property of giving a system the specific combination of capabilities it needs to be useful. Every one of the platforms in this series so far — the vulnerability checker with SAST/RAG/sandboxed execution, the LangGraph agent with tool use and a vector DB — has all three ingredients by design. That’s not a criticism of the architecture; it’s the reason the architecture is useful. It’s also exactly why the guardrail harness and human-in-the-loop review from the first post in this series aren’t optional extras — they’re the thing standing between “useful agent” and “lethal trifecta.”
Breaking the chain
Since you generally can’t remove all three capabilities and still have a useful agent, defenses focus on breaking the chain between them rather than eliminating any single ingredient outright:
- Segment private-data access from untrusted-content processing. An agent that summarizes arbitrary web pages shouldn’t be the same agent that holds database credentials.
- Constrain the exfiltration surface. If an agent can only write to a specific, allow-listed set of destinations, a successful injection has nowhere useful to send data.
- Treat all ingested content as data, never as instructions — architecturally, not just with a prompt telling the model to be careful. This is the same principle as never building a SQL query by string-concatenating user input.
- Human approval before high-privilege actions — the same checkpoint pattern from the guardrail harness in the vulnerability-orchestration platform, applied generally: anything that reads sensitive data and can also communicate externally gets a checkpoint between the two.
The takeaway
Capability and risk scale together in agentic systems in a way they mostly didn’t in traditional software. The more useful you make an agent — the more data it can see, the more content it can process, the more it can act on your behalf — the closer you get to all three trifecta conditions being true at once. Designing for this isn’t a one-time checklist item; it’s a constraint that has to shape the architecture from the start, the same way the guardrail harness, the sandboxed runner, and the human review step were load-bearing parts of the vulnerability-orchestration platform rather than bolted-on afterthoughts.
References
- Simon Willison — The lethal trifecta for AI agents
- HiddenLayer — How the Lethal Trifecta Exposes Agentic AI
- Oso — Understanding the Lethal Trifecta of AI Agents
- Cyera — How to Solve the Lethal Trifecta in AI Agents
- The Promptware Kill Chain: How Prompt Injections Evolved Into a Multistep Malware Delivery Mechanism (arXiv)
Leave a Reply