How data actually escapes
Exfiltration rarely looks like a file upload. It looks like a picture, a link, or a slightly odd search query. Click each channel to see the trick.
In 60 seconds
How data actually escapes
Exfiltration rarely looks like a file upload. It looks like a picture, a link, or a slightly odd search query. Click each channel to see the trick.
Tap any box in the diagram
The model writes an image pointing at the attacker's server, with the secret baked into the URL. Your chat interface renders images automatically. The fetch happens with no click, no warning, and the secret lands in a web server log. This is the most common real-world agent exfiltration and it is entirely silent.
A leak needs surprisingly little bandwidth
Defences, strongest first
- 1
Outbound allow-list
Network egress from the agent's environment is restricted to domains you named. An unknown host simply does not resolve. This kills every channel above at once. - 2
Do not auto-render remote content
Block automatic image loading and remote fetches in the output surface. Proxy or strip anything that reaches out. - 3
Keep secrets out of context entirely
The agent asks a tool to "use the API key", and the tool holds the key. If the key never enters the context window, it cannot be written into a URL. - 4
Strip URLs from generated output
Only allow links to domains on your list. Rewrite or remove the rest before rendering. - 5
Watch for weird URLs in tool calls
Alert on long query strings, base64-looking blobs, and unfamiliar hosts. Detection, not prevention — but it tells you when you were hit.
Watch and read more
Lab
Four exfiltration channels demonstrated, then closed at the network layer.
The problem
import http.server, socketserver
# Minimal listener — watch what arrives in the query string.
class H(http.server.BaseHTTPRequestHandler):
def do_GET(self):
print("EXFIL:", self.path)
self.send_response(200); self.end_headers()
socketserver.TCPServer(("", 8899), H).serve_forever()You are done when
Hard questions
Try to answer before you reveal. If you can answer these, you understood the lesson.
Q1You blocked all outbound HTTP. Explain how DNS still leaks, and what you must configure.Reveal
<secret>.attacker.example reaches the attacker's authoritative nameserver even though the subsequent TCP connect is refused — the query itself carries the payload. You must force all resolution through a resolver you control, allow-list the names it will answer, and drop everything else. An egress policy that filters HTTP but leaves DNS open has a hole exactly the width of a hostname.Q2An agent leaks one bit per request — a page either loads or does not. How many requests to exfiltrate a 40-character API key, and what does that tell you?Reveal
Questions people ask
Can data leak through DNS?
Yes — a lookup of SECRET.attacker.example leaks the secret to the attacker's DNS server even if the connection is then blocked. If you are locking down egress, lock down DNS resolution too, or the wall has a hole in it.
Do markdown images really get fetched automatically?
In many chat interfaces, yes, historically. Several products have shipped fixes after exactly this bug. If you are building a chat UI that renders model output, assume remote image loading is an exfiltration channel until you have specifically closed it.
Is this only about secrets?
No. Personal data, private conversations, internal plans and customer records all matter, and in most places leaking them carries legal weight. A leak does not need to involve a credential to end your week badly.
How do I test my own system for this?
Run a controlled exercise: put a fake secret in context, then have a test page instruct the agent to leak it through each channel above. Watch your egress logs. If your fake secret appears anywhere outside, you have a live hole. Do this only on systems you own.
Lesson test
5 questions. Get 3 right (60%) to pass and complete this lesson.
Sign in with your phone number to take the test and save your progress