Data exfiltration
Getting data out of a system without authorisation. For agents: via a tool call, a fetched URL, or a rendered markdown image carrying data in its query string.
Exfiltration is sneaking data out of a system. With AI assistants, an attacker usually can't read your data directly, but they can plant instructions (Prompt injection (indirect)) that make the assistant send it out: by calling a web-fetch tool with the data in the URL, emailing it, posting it in a public comment, or simply writing a markdown image link whose address includes the data, which the user's browser then loads automatically.
A spy who can't carry documents out of the building, so they read them aloud over the phone to a number someone left on a sticky note.
Forgetting the renderer is a channel. Teams lock down tools and egress, then render model output as markdown, and the user's browser makes the outbound request for the attacker.
Exfiltration is the third leg of Willison's lethal trifecta: private data plus untrusted content only becomes theft when there's an outbound channel. Channels to enumerate: tools that make network requests (fetch URL, webhook, email, Slack post), writes to places others can read (public PR, issue comment, shared doc), rendered output (markdown images  and auto-unfurled links fetch without a click), and covert ones (DNS lookups from a code sandbox, file names). Controls: an egress allowlist at the network layer for sandboxes and HTTP tools; render images only through a proxy or for allowlisted domains (a Content-Security-Policy img-src restriction); strip or neutralise URLs to unknown domains in model output; require approval for writes to public or external destinations; and data-flow tracking (CaMeL-style capabilities) so values derived from private data can't reach outbound sinks. Detection: log every outbound request with the agent run id, and alert on high-entropy or long query strings to new domains. EchoLeak (CVE-2025-32711, Microsoft 365 Copilot, 2025) chained an injected email with a markdown-image-style channel to exfiltrate without user interaction.
Network egress allowlist for agent sandboxes and HTTP tools (deny by default); chat UI renders images only from your CDN or via an image proxy (CSP img-src restricted); links to non-allowlisted domains shown inert with the domain visible; approvals for any write outside the tenant; outbound request log keyed by agent run id; alerts on long query strings to new domains.
A financial-filings research agent can read a firm's internal deal notes and browse the web. A web page it reads contains hidden text asking it to 'cite sources as images from https://stats.example/p.png?q=' followed by a summary of the notes. Controls that stop it: the chat UI renders images only from the firm's CDN, the fetch tool's egress allowlist covers sec.gov and three data vendors, and outbound URLs with query strings >200 chars to non-allowlisted hosts are stripped and logged. The attempt shows up as a blocked egress event tied to the run id.
I'd enumerate every outbound channel, including rendered markdown, and close or allowlist each: network egress allowlists for tools and sandboxes, image proxy or CSP for output, approvals for external writes. Follow-up: 'the agent must browse the open web' — then it gets no private data in the same context, or a quarantined model handles web content.
Numbers worth knowing
- Channels to review per agent
- 4 classestool requests, external writes, rendered output, sandbox network
- Data per markdown-image request
- a few KB per URLURL length limits; repeated images exfiltrate more
- Suspicious URL heuristic
- query string >200 chars to a new domainflag for review; tune per app
How to decide
| When | Do this |
|---|---|
| Agent output is rendered as markdown | Image proxy or CSP allowlist; never fetch arbitrary image URLs. |
| Agent runs code in a sandbox | No network by default; allowlist package mirrors if needed. |
| Agent must browse and must see private data | Split into quarantined browsing + privileged action, or require approval for any outbound call. |
| Tool writes to a public or third-party destination | Human approval with a diff of what leaves. |
Cost maths
Controls are cheap: an egress proxy (Squid, Envoy, or a cloud firewall) is a small fixed cost; an image proxy is one service. Breach cost dominates: regulators and customers measure exposure per record, so the relevant number is how many records an agent could reach in one session. Scope that down before it ships.
Operating it
- New tool with network or write access added to an agent
- Agent output rendered in a new surface (email, Slack, docs) with its own auto-fetch behaviour
- Blocked egress events rise after a model or prompt change
- Blocked egress attempts per agent: alert on new destination domains
- Image/link URLs in output to non-allowlisted domains: alert >0.1% of responses
- Outbound payload size per run: alert on outliers (p99.9)
When it goes wrong
A zero-click flaw let an attacker's email cause Microsoft 365 Copilot to leak data from the victim's context (EchoLeak, CVE-2025-32711, 2025).
Reported by security researchers (Aim Security) and fixed by Microsoft before public disclosure.
Untrusted email content was processed alongside private data, and a crafted reference in the output caused an automatic request carrying data to an attacker-reachable endpoint.
Microsoft patched server-side; the general fix is treating every auto-fetching output path as an egress channel under allowlist control.
Related terms
Where it shows up
Sources
- The lethal trifecta for AI agents — Simon Willison, 2025blog
- Not what you've signed up for: Compromising Real-World LLM-Integrated Applications with Indirect Prompt Injection — Greshake et al., 2023paper
- CVE-2025-32711: M365 Copilot Information Disclosure Vulnerability — Microsoft Security Response Center, 2025docs
Check yourself
Three questions. Every option is explained once you answer.