Blog / 31 October 2026
Deep dive · 31 October 2026 · 7 min read
The lethal trifecta: how AI agents leak data, and how to break it
An AI agent can be made to leak data whenever it has three things at once: access to private data, exposure to untrusted content, and a way to send data out. Simon Willison calls this the lethal trifecta; since no filter reliably stops the injected instruction, the dependable fix is to remove one leg, and the leg you can most often control is the way out.
01What is the lethal trifecta?
Simon Willison named it in June 2025. The three capabilities are access to your private data, exposure to untrusted content, and the ability to communicate externally in a way that could be used to steal that data. Any one is fine and most pairs are manageable. When an agent has all three, an attacker who can put text in front of it can ask it to read something private and send it somewhere.
The reason is the one behind every prompt injection: LLMs follow instructions in content. A model cannot reliably tell the instructions its user gave from instructions inside a web page, an email, an issue or a tool result it was asked to process. Willison's post lists many products that shipped this class of flaw, including Microsoft 365 Copilot, GitHub's official MCP server, GitLab Duo, ChatGPT, Google AI Studio, Slack and Amazon Q.
Coding agents fit the pattern by default. They read repositories, dependencies and web pages written by strangers; they run with the developer's files and credentials; and they can usually open network connections.
02How AI agents leak data: markdown images, links and tool calls
The way out does not have to look like a network call. In 2023 Johann Rehberger showed markdown image exfiltration against Bing Chat: an injected page told the model to output an image whose URL carried data from the conversation as a query parameter, and the browser fetched that URL to render the image, with no click needed. The fix he observed was a Content Security Policy that only allowed images from a few Bing domains.
EchoLeak, CVE-2025-32711, took the same idea to an enterprise assistant. NVD records it as AI command injection in Microsoft 365 Copilot that allows an unauthorized attacker to disclose information over a network, with a CVSS 3.1 score of 9.3 from Microsoft. The researchers' paper describes a single crafted email that needed no user interaction. The chain evaded Microsoft's prompt-injection classifier, slipped past link redaction with reference-style markdown, used images that are fetched automatically, and routed the request through a Microsoft Teams URL that the Content Security Policy allowed.
For agents with tools the channel is often more direct: an HTTP request, a curl in a shell, a DNS lookup, a comment posted to a public issue, or a pull request. Every one of them is a way out, so all of them belong to the third leg.
03Why filters and classifiers do not close the gap
Detection is worth having, but it is probabilistic. Willison's point is that a guardrail product claiming to catch 95 percent of attacks is a failing grade in security, because an attacker only needs the attempt that gets through and can keep trying. EchoLeak is a clean example: the chain included a bypass of the classifier that was there to stop it.
Meta reached a similar conclusion from the design side. Its Agents Rule of Two, published in October 2025, says that until injection can be reliably detected and refused, an agent should satisfy no more than two of three properties in a session: it can process untrustworthy inputs; it can access sensitive systems or private data; it can change state or communicate externally. If a task needs all three, the agent should not run it autonomously; a human should approve, for example. Meta's third property is wider than Willison's: it covers changing state, not only sending data out.
04How to break the trifecta at the network layer
Of the three legs, the way out is often the one you can remove without breaking the task. Agents need to read untrusted content to be useful, and they usually need some private data. Few need to reach arbitrary hosts. So close the network by default, allow the hosts the task needs by name, and enforce the rule outside the agent's environment, where code running inside cannot rewrite it.
An allow-list narrows the channel; it does not remove it. Data can still be sent in a request body to an allowed host, and broad entries are risky. Anthropic's Claude Code sandbox documentation warns that allowing a broad domain such as github.com can create paths for data exfiltration, and that a proxy deciding by hostname without inspecting TLS may be bypassed with domain fronting. DNS is a channel too, so the sandbox should not be free to query resolvers of its choosing.
Two more measures shrink what can leak. Keep credentials out of the agent's environment by adding them in an egress broker on the trusted side, so a hijacked agent cannot send the key itself, and record every request the broker makes. And where output is rendered, do not let the model's text fetch arbitrary images or links.
- Deny all egress by default; allow named hosts, not whole platforms.
- Enforce the rule on the host, outside the sandbox, including DNS.
- Keep API keys outside the sandbox and add them in a broker on the way out.
- Log every outbound request, allowed or refused.
- Do not auto-load images or links from model output in a rendering client.
05When an agent needs all three legs
Some tasks need private data, untrusted input and a way out at once: triaging a public issue against private code and posting a reply, for example. Then split the work so no single session holds all three, or put a person in the path. Run the reading step in a session with no network, pass a narrow result to a second session that can act, and require approval for the action itself.
Narrow each leg even when you cannot remove it. Let the agent's machine see one project folder, not the home directory. Give it a token scoped to one repository. Make outgoing actions that publish or send wait for a named approver. None of this needs the model to recognise an attack, which is the point.
Takeaways
- The lethal trifecta is private data, untrusted content and a way to send data out, all held by one agent.
- Markdown images, reference-style links, DNS lookups and ordinary tool calls are all ways out.
- EchoLeak, CVE-2025-32711, leaked Microsoft 365 Copilot data from one email, bypassing a classifier and link redaction.
- Meta's Agents Rule of Two allows at most two of untrusted input, sensitive access and external action per session.
- Close egress by default, enforce it outside the sandbox, keep keys in a broker, and require approval when all three legs are needed.
Where kosa8 fits
kosa8 targets the third leg. Each agent runs in a microVM with its own kernel that sees one workspace folder. The network is closed except for hosts on an allow-list you write, enforced on the host where nothing inside the sandbox can change it, and the sandbox's DNS questions are answered there too, so names off the list are refused. API keys stay on the host: an egress broker adds them on the way out, so there are 0 real keys inside the sandbox, and requests are recorded in the hash-chained audit log. Risky actions can wait for one or two named human approvers. The kosa8 docs are plain about the limit: the broker does not inspect request bodies, so data the agent can read can still be sent to an allowed host.
Check yourself · +100 XP
An agent reads untrusted web pages and has your private files. Which change removes the lethal trifecta?
The trifecta needs all three legs. A classifier and a system-prompt instruction lower the odds but can be bypassed; removing the ability to communicate externally takes a leg away.
Questions people ask
Who coined the lethal trifecta?
Simon Willison, in a June 2025 post naming the combination of private data access, exposure to untrusted content, and the ability to communicate externally.
What is markdown image exfiltration?
Injected instructions make the model output an image whose URL contains stolen data. When the client renders the image, it requests that URL and delivers the data to the attacker's server without a click.
Is a domain allow-list enough to stop AI agent data exfiltration?
It narrows the channel but does not close it. Data can be sent to an allowed host, and broad domains add paths. Pair it with keys kept outside the sandbox, logging, and approval for outgoing actions.
Sources
- The lethal trifecta for AI agents: private data, untrusted content, and external communication — Simon Willison
- Bing Chat: Data Exfiltration Exploit Explained — Embrace The Red (Johann Rehberger)
- CVE-2025-32711 — NIST National Vulnerability Database
- EchoLeak: The First Real-World Zero-Click Prompt Injection Exploit in a Production LLM System — Reddy and Gujral, arXiv
- Agents Rule of Two: A Practical Approach to AI Agent Security — Meta AI
- Configure the sandboxed Bash tool (security limitations) — Claude Code docs
- AI agent network allow-list — kosa8 guides
- Give an AI agent API keys safely — kosa8 guides
- Human approval for AI agent commands — kosa8 guides
Written by the kosa8 team. Every kosa8 command was checked against the CLI, and every claim about another product links to that product's own documentation. Spotted a mistake? Tell us.
Try it on your own machine
Give your next agent its own sealed machine.
One line installs kosa8 on your own machine. Every feature, plans from $29 a month.