AccuroAI
Products
What We Do
Solutions
Company
Resources
Book a demo
← Blog·Prompt DLP14 min read

AI Agent Data Exfiltration Prevention: Stopping Leaks Before They Leave

In the most common attack the agent never contacts the attacker. Your own client does, rendering a markdown image and issuing a GET nobody clicked. Here are the four paths data takes out, why domain allowlisting meters exfiltration rather than stopping it, and which controls hold up against an attacker who has read them.

A
Atul B
Co-Founder
Sep 17, 2026

AI agent data exfiltration is prevented by inspecting every outbound action inline and stripping or blocking sensitive data before it leaves, because an agent moves data as a byproduct of doing its job. No single step looks suspicious, no human decision triggers the leak, and detection after the fact arrives after the data is gone.

The most useful thing to understand first is that in the most common attack, the agent never opens a connection to the attacker at all. Your own software does it, on your own machine, using your own credentials.

How do AI agents exfiltrate data without being compromised?

Here is the mechanism, precisely, because the precision changes which control you reach for.

The model emits text. It does not make an outbound request. The request is made by the renderer: the browser, the desktop chat client, the IDE webview, the email client. The sequence runs like this.

Attacker-controlled text enters the model's context. It might be a web page, an inbound email, a file name in a repository, a document in a retrieval index, a calendar invite, or the description field of a tool. That text instructs the model to find something sensitive already in its context and emit a markdown image pointing at an attacker domain, with the secret in the URL. The client renders the markdown into HTML, producing an image tag. The browser then issues an unsolicited GET request to fetch the image. No click is required. The attacker's web server logs the request, returns a single transparent pixel, and the user sees nothing at all.

Three properties make that hard to stop. The channel is an ordinary GET request made by a trusted client over the user's own network path, so it looks exactly like loading an image. The payload capacity is bounded only by URL length. And the attacker never needs to control a request header or body, which is why controls that inspect request payloads do not engage.

This is not new and it is not theoretical. Roman Samoilenko published the first public writeup in March 2023, against the ChatGPT web client, describing it exactly: "Once the image loading is started, sensitive data is sent to attacker's remote server along with the GET request." Johann Rehberger then got the first vendor fix, reporting it to Microsoft in April 2023 and seeing Bing Chat patched that June, before driving the same disclosure across Bard, GitHub Copilot Chat, Microsoft 365 Copilot, Claude Code and Slack.

Now read what the US National Vulnerability Database published on 6 July 2026, about OpenAI's own Codex desktop application for macOS, CVE-2026-14898:

"The app automatically fetched that URL when rendering the response, sending the embedded data to an attacker-controlled server without a separate user click. Successful exploitation could exfiltrate secrets and other information accessible in the Codex session, including API keys, source code, and data returned by connected tools."

Thirty-nine months separate those two sentences. One was written by an independent researcher on Medium, the other by NVD about the vendor that popularized the technology. Two more CVEs published on 18 June 2026 against Eclipse Theia describe attack chains "leading to data exfiltration via Markdown image rendering." The primitive has outlived three years of fixes.

MITRE ATLAS tracks the lineage with dated entries: ChatGPT and Google Bard in 2023, Slack AI in 2024, Copilot Studio and Cursor in 2025, Microsoft 365 Copilot as EchoLeak in 2025. One clarification on that list, since it is often reported carelessly: the Slack AI case used a markdown link and required the user to click it. The image variants do not. ATLAS also assigns the class its own technique identifier, AML.T0086, with maturity marked as realized, meaning observed in the wild rather than demonstrated in a lab.

The four paths data actually takes out

Inventory these before choosing controls, because they terminate in different places and only two of them cross a network boundary you own.

PathWhat carries the dataWhere the control has to sit
Rendered outputA markdown image or link fetched by the user's clientThe renderer, and the content security policy around it
Tool callArguments to an outbound tool: an HTTP fetch, an email send, a webhookInline, between the agent and the tool
File writeA commit, a PR, a file dropped in a synced folder or a shared datasetThe repository and storage boundary
Downstream actionA legitimate SaaS write that happens to land somewhere the attacker can readThe action's authorization, before it executes

Last verified: September 2026.

The fourth is the one teams miss. In the GitHub MCP flow that Invariant Labs published in 2025, nothing left the network perimeter at all. The agent read a private repository and wrote the contents into a pull request on a public one. Every request was to github.com, authenticated, authorized, and logged as normal. The exfiltration was a feature working correctly.

Who actually makes the outbound request

Everything above assumes the fetch happens on the employee's machine. That assumption is worth testing, because three different parties can make it, and only one of them is inside your perimeter.

The user's client. The classic case. Your browser or IDE renders the markdown and fetches the image. Your egress controls and your content security policy apply, which is why those are the controlling mitigations for this variant.

A third party's infrastructure. In an advisory covering a deprecated Slack MCP server, recorded as CVE-2025-34072, the agent posts a message containing an attacker-crafted link, and Slack's own link preview bots fetch it. The description is explicit that the preview services "will then issue outbound requests to the attacker-controlled URL, resulting in zero-click exfiltration of private data." Neither your browser nor the agent's host made that request, so neither your proxy nor your endpoint agent sees it.

The AI vendor's cloud. This is the one with no enterprise answer. In September 2025, researchers at Radware published work on ChatGPT's deep research agent showing exfiltration performed by the agent's own server-side browsing tool. Their framing is worth quoting because it states the problem exactly: "Unlike prior research that relied on client-side image rendering to trigger the leak, this attack leaks data directly from OpenAI's cloud infrastructure, making it invisible to local or enterprise defenses." They also noted the model was persuaded to base64-encode the data first, with the encoding framed in the injected instruction as a security measure. No CVE was assigned; the researchers reported it in June 2025 and it was acknowledged as resolved that September.

Sit with that third case for a moment. Your secure web gateway, your egress proxy, your endpoint data loss prevention, and your content security policy all sit on the client side of a boundary the request never crosses. There is no network control you can buy that sees it. What remains are the vendor's own controls, and your procurement decisions about which connectors and which data an agent may reach in the first place, which is an argument for scoping access rather than for inspecting traffic.

Why doesn't traditional DLP catch agent exfiltration?

Because legacy data loss prevention was built around a human moving a file, and none of those assumptions hold.

There is no file. The data is assembled in a context window from several sources and leaves as characters in a URL or as arguments to a function call. There is no user action to intercept, because nobody clicked send. There is no unusual destination in three of the four paths above, since the traffic goes to github.com, to your own SaaS tenant, or to a domain on somebody's allowlist. And the volume looks nothing like an exfiltration, because a few hundred bytes at a time over four days does not trip a threshold tuned for someone copying a database.

What does engage is inspection of the outbound content itself, at the moment the agent acts, which is why inspecting the outbound context before it reaches the model or the tool is the control that matches the shape of the problem. We compare the two models directly in AI DLP versus legacy DLP.

Can prompt injection make an agent exfiltrate data?

Yes, and the more useful question is whether the defenses being sold to stop it work. The published evidence says most do not.

In October 2025 a team including researchers from Google DeepMind, OpenAI and ETH Zürich tested twelve recent prompt-injection and jailbreak defenses using adaptive attacks, meaning attacks tuned against each specific defense rather than a fixed benchmark. They achieved attack success rates above 90% against most of them. The detail that matters for procurement is the next clause: the majority of those defenses had originally reported near-zero attack success rates.

That is not a claim that guardrails are worthless. It is a claim about what their evaluation proves. A defense measured against an attacker who has not read it tells you very little about an attacker who has. OWASP's 2026 Top 10 for LLM Applications turned this into a procurement rule, advising readers to reject static-only attack-success claims, and states plainly that no reliable prevention mechanism exists today.

The practical consequence is a split worth holding on to. Some controls reduce the chance an injection succeeds, and those degrade against a motivated attacker. Other controls bound what happens once it does succeed, and those hold. Budget accordingly. Our annotated walkthrough of the injection classes is in inter-agent prompt injection, and the supply-chain variant in tool poisoning.

Domain allowlisting does not prevent exfiltration. It sets the bit rate.

This is the single most important idea in this article, and the vendor with the best implementation of the control said it before anyone broke it.

The standard mitigation is an allowlist: restrict which domains the agent, or the renderer, may fetch. Microsoft applied it to Bing Chat in 2023 by restricting images to four bing.com origins. It has since been defeated three distinct ways, and in two of them the allowlist worked exactly as designed.

An open redirect on an allowlisted domain. Tenable published research in March 2025 showing Bing's own indexed-link wrapper functioning as an open redirect, so a URL that passes the check lands wherever the attacker chose. Tenable recorded the issue as unresolved at the time of publication, and no CVE was assigned.

A fetcher that is itself on the allowlist. EchoLeak, tracked as CVE-2025-32711 against Microsoft 365 Copilot, worked by abusing a Microsoft proxy that the content security policy already permitted. The allowlist was correct. One of the permitted origins would fetch arbitrary URLs on request. Note that the severity figure in circulation is contested: Microsoft scored it 9.3 critical, and NVD's own primary score is 7.5 high, the difference being entirely the scope metric.

Pre-laundered per-character URLs. This is the one that changes the model. Rather than constructing a URL the allowlist would reject, seed a crawler in advance with thirty-six URLs, one per alphanumeric character, then have the agent fetch them in sequence. The allowlist becomes an alphabet. Roughly 5.2 bits leave per fetch, so a sixteen-character API key is about twenty-five requests to destinations that were each, individually, permitted. Rehberger noted this property as early as December 2023. MITRE ATLAS records it being carried out against ChatGPT in September 2025, describing researchers who bypassed the control "by supplying an indexed dictionary of preconstructed static URLs and instructing ChatGPT to open URLs corresponding to individual characters to exfiltrate the collected data."

Generalize that and the conclusion is uncomfortable. Any control that still lets the agent make attacker-observable requests to some set of destinations leaks data at a rate set by the size of that set, even when the attacker controls none of them. An allowlist meters exfiltration. It does not close it.

The most useful document on this is OpenAI's own retrospective on URL-based exfiltration, which is worth reading precisely because it was written after the bypasses rather than before them. Its title page is dated January 2025, though the PDF metadata indicates January 2026, which fits the sequence: the client-side URL check shipped in December 2023, Tenable and others broke it through 2025, and the paper explains why the approach failed. Two figures from it are worth carrying into your own design review. A curated static allowlist "covers only approximately ten percent of URLs that our users were actually visiting." And false unsafe determinations "actually end up causing user fatigue," which is the documented path by which a control gets relaxed until it stops mattering.

Two things close the channel rather than metering it. A server-side fetcher that strips data-bearing components from the URL before any request leaves, which is OWASP's own prevention guidance for improper output handling. And not auto-rendering remote content in the client at all.

Should you block the agent or redact the data?

Redact by default and block by exception, for the reason that decides most security controls in practice: a control that stops work gets switched off.

An agent that cannot complete a task produces a ticket asking for the control to be relaxed, and enough of those produce an exemption. An agent that completes the task with a tokenized placeholder in place of the customer's card number produces nothing, which is the correct outcome. Blocking earns its place for a narrow class: irreversible actions, unknown destinations, and credential material, where completing the task is worse than failing it. We make the full argument in redact, don't block, and inline redaction of PII, PHI, source code and secrets covers the detection side.

What actually works

Sorted by whether the published evidence supports it, which is a different sort order from most vendor comparison tables.

ControlVerdict
Input and output classifier filteringReduces casual attempts. Degrades sharply against an adaptive attacker
Output schema validationCatches format violations only. A schema-valid response still carries a malicious payload
Delimiting or marking untrusted dataHelps against non-adaptive attacks. Bypassed when the attacker tunes for it
Stripping invisible charactersReal but narrow. Does nothing about visible-text payloads
Static domain allowlistInadequate. Roughly 10% coverage, defeated by open redirects
Dynamic crawl-based allowlistBetter, still a bounded-bandwidth channel
Server-side fetcher stripping data-bearing URL partsCloses the channel
Least privilege per operation, credentials outside the model's reachBounds blast radius. Survives adaptive attackers
Deterministic policy re-validating arguments at execution timeBounds blast radius. Survives adaptive attackers
Removing one leg of the trifecta by designStructurally sound

Verdicts follow OWASP's 2026 guidance and the adaptive-attack literature. Last verified: September 2026.

One entry deserves singling out because it appears in so many threat models. Running model output through an industry-standard HTML sanitizer does not address this, and the reason is structural rather than a configuration mistake. When Legit Security disclosed a prompt injection in GitLab Duo in May 2025, they described it precisely: the content "is passed into the 'sanitize' function of DOMPurify, an industry-standard library, to sanitize HTML. However, while DOMPurify is excellent at preventing most XSS attacks, certain HTML tags like <img>, <form>, and <a> aren't removed by default."

An image tag is supposed to survive sanitization. Preserving it is what the sanitizer is for. This is not cross-site scripting, and the exfiltration primitive is a legitimate, deliberately retained HTML feature. Which is why the fix that has never been publicly bypassed is not better sanitization but removing the capability: when GitHub addressed this in Copilot Chat in 2024, the resolution was that it stopped rendering markdown images at all.

That last row deserves explanation because it is the cheapest thing on the list. Two independent formulations say the same thing. Simon Willison's lethal trifecta, published June 2025, names private data, untrusted content, and external communication. Meta's Agents Rule of Two, published October 2025, says an agent should satisfy no more than two of: processing untrustworthy input, accessing sensitive data, and changing state or communicating externally. Remove any one leg and the exfiltration path closes architecturally rather than probabilistically. An agent that reads untrusted web content and holds customer data should not also have an outbound channel, and splitting it into two agents with a reviewed handoff is usually easier than defending the combined one.

For teams who want the research direction, Google's CaMeL work in 2025 separated control flow from data flow with capability-enforced tool calls and solved 77% of an agent benchmark with provable security properties, against 84% for an undefended agent. A seven-point capability cost for a structural guarantee is a trade many enterprises would take today if the tooling were ready.

How do you detect exfiltration you have already suffered?

Mostly you do not, and planning around that fact is more useful than pretending otherwise.

The July 2026 compromise of Hugging Face infrastructure by autonomous agents is the clearest published case. Exfiltration ran for roughly four and a half days before detection, staged through datasets on a legitimate, allowlisted destination. The data was chunked and encoded specifically so that a naive text scan of the logs would miss it. What made the incident reconstructable afterward was roughly 17,600 recorded agent actions across about 700 runs, recovered from the sandbox logs.

Anthropic put the general case plainly in May 2026: "once a poisoned tool return has steered the agent into exfiltrating data, the log just shows a successful, authorized API call. There's no after-the-fact signal to find."

So the honest division of labor is this. Prevention happens inline, at the moment of the action, because that is the only point where the decision is still reversible. Reconstruction happens from a structured action record, which is a different artifact from a log you hope to search. We cover building that record in why every agent action needs an audit log.

Where to start this quarter

Four moves, in order of ratio between effort and risk removed.

Inventory your egress paths against the four in the table, including the two that never cross your perimeter. Most teams have controls on one of the four and believe they have coverage. The repository is an egress path too, which is why coding agents pushing commits belong in the same inventory as the customer-facing ones.

Apply the trifecta test to each agent and find the ones holding all three legs. Those are your candidates for splitting, and the exercise usually takes an afternoon.

Put per-action egress policy on every tool an agent can call, evaluated on the arguments rather than the destination, since three of the four paths end somewhere legitimate. This is also the point where stopping exfiltration at the tool call rather than in the postmortem stops being a slogan and becomes a configuration.

Then fix the renderer, because it is the path most likely to be uncovered. Disable auto-rendering of remote images in agent surfaces, or route them through a server-side fetcher that strips query and path data before the request leaves. It is a small change that closes the oldest hole on this list.

If you are evaluating vendors on this, the exfiltration controls to score them on are in our RFP template, and the question worth asking first is whether their evaluation was adaptive. The answer tells you most of what the rest of the meeting will confirm.

See AccuroAI in action.
30-minute demo tailored to your top AI risk.
Book a demo
More from the blog
See AccuroAI in action.

Book a 30-minute demo and see how security teams use AccuroAI to discover, govern, and protect every AI asset across their organization.

Book a demoRun the free assessment

15 enterprises secured · under 38ms p99 · live on your own estate in 72 hours