Datenexfiltration: wie LLMs Daten aus dem Kontext leaken — und der Markdown-Bild-Trick
Von Jochen Maurer
Vektor 4 der Serie Fable 5 — war es da, ist es weg. Zurück zum Hub.
Was es ist
Das Modell gibt aus, was es nicht ausgeben soll. Drei Wege:
- Es plappert sensible Daten aus seinem Kontextfenster aus — System-Prompt, andere Nutzerdaten, interne Dokumente aus dem RAG.
- Es wird per Injection angewiesen, Daten an einen externen Kanal zu schleusen. Der klassische Trick: das Modell einen Markdown-Bild-Link mit den Daten als URL-Parameter rendern lassen —
. Beim Anzeigen lädt der Client das „Bild” automatisch und liefert die Daten frei Haus. - Es leakt über Fehlermeldungen und Debug-Output Struktur und Secrets.
Warum es funktioniert
Alles, was im Kontextfenster steht, ist für das Modell prinzipiell sagbar. Es gibt keine modellinterne Schranke, die „das ist geheim” von „das darf raus” trennt — dieselbe fehlende Daten/Instruktion-Grenze wie bei der Prompt Injection. Wer einen System-Prompt mit eingebetteten Keys oder Geschäftslogik füttert, hat diese Geheimnisse in eine Schicht gelegt, die per Formulierung extrahierbar ist.
Der Exfiltrations-Kanal über aktive Inhalte funktioniert, weil AI-Antworten oft als Rich Text (Markdown, HTML) im Browser gerendert werden. Jeder automatisch geladene Link — Bild, Stylesheet, Preview — ist ein Abfluss, den das Modell auf Anweisung hin selbst baut.
Wenn du KI in dein Produkt einbaust
Multi-Tenant-Setups sind der heikelste Fall. Wenn dein RAG-Index die Dokumente mehrerer Kunden enthält und die Filterung schwächelt, sieht Kunde A die Daten von Kunde B — der teuerste Vertrauensbruch im B2B-SaaS. System-Prompts mit eingebetteten API-Keys oder Geschäftslogik werden per Injection extrahiert. Und jede AI-Antwort, die in einem Browser gerendert wird, ist ein potenzieller Exfiltrationskanal über aktive Inhalte.
Selbst ausprobieren
Der Abfluss-Kanal ist abstrakt, bis man ihn einmal feuern sieht. PortSwigger hat ein Lab, in dem modellgenerierte Ausgabe ungefiltert in die Seite gerendert wird — derselbe Kanal, den der Markdown-Bild-Trick missbraucht.
Hands-on (≈20 Min, Sandbox):
- In der PortSwigger Web Security Academy das Lab „Exploiting insecure output handling in LLMs” öffnen.
- Über einen Produktkommentar eine indirekte Injection platzieren, die den LLM einen aktiven Inhalt ausgeben lässt — hier einen XSS-Payload.
- Beim Anzeigen rendert die Seite die Modell-Antwort ungefiltert, und der Payload feuert im Browser eines anderen Nutzers. Du siehst live, wie der Anzeige-Schritt zum Exfiltrationskanal wird.
Real war das mehrfach, dokumentiert von Johann Rehberger: den Markdown-Bild-Trick führte er unter anderem gegen ChatGPT-Plugins (2023) und GitHub Copilot Chat (2024) vor. Eine Injection ließ das Tool einen Bild-Link mit dem Chat-Inhalt als URL-Parameter rendern, der Client lud das „Bild” automatisch und lieferte die Daten frei Haus an den Angreifer-Server.
Verteidigung
- Tenant-Isolation auf Datenebene, nicht auf Prompt-Ebene. Der Retrieval-Filter muss serverseitig erzwungen sein, bevor irgendetwas ins Kontextfenster kommt — niemals per Anweisung an das Modell („zeige nur Daten von Tenant X” ist keine Sicherheitsgrenze).
- Keine Secrets im System-Prompt. Was geheim ist, gehört in den Code, nicht in den Kontext. Dann ist eine erfolgreiche Extraction wenig wert.
- Output-Sanitisierung vor dem Rendern: Markdown-Bilder und Links aus externen oder modellgenerierten Quellen neutralisieren.
- Ausgehende Allowlist für alles, was der Client oder Agent kontaktieren darf — das schließt den Markdown-Exfil-Trick und deckt sich mit der Egress-Kontrolle aus dem Confused-Deputy-Vektor.
Die Umsetzung steht in der Referenzarchitektur, Layer 2 (Tenant-Filter) und Layer 4 (Output-Sanitisierung).
Teil der Serie
Hub · Prompt Injection · Jailbreaks · Confused Deputy · Datenexfiltration · Capability-Extraction · Referenzarchitektur