Seine Aufgabe war ein Issue, sein Token konnte die ganze Org lesen
Noma Securitys GitLost zeigte, wie ein nicht authentifizierter Fremder ein öffentliches GitHub-Issue öffnet und GitHubs KI-Agent dazu bringt, den Inhalt eines privaten Repositorys als öffentlichen Kommentar zurückzuposten. Die Prompt Injection machte die Schlagzeile. Der Token des Agents, gescoped auf die gesamte Organisation statt auf das eine Issue, das er triagierte, bestimmte, wie weit das Leak reichen konnte. Diese Lücke zwischen dem, was eine Aufgabe braucht, und dem, was die Umgebung hält, ist der Teil, den man mitnehmen sollte, und der Teil, den du anders designen kannst, wenn du den Agent selbst hostest.
Ein nicht authentifizierter Fremder öffnete ein Issue in einem öffentlichen GitHub-Repo, schrieb einen Absatz und wartete. GitHubs KI-Agent las das Issue, spazierte in die privaten Repositories der Organisation und postete eine private README als öffentlichen Kommentar zurück. Der Absatz war der Auslöser. Der Token des Agents, gescoped auf die gesamte Organisation statt auf das eine Issue vor ihm, ist der Grund, warum das Leak so weit reichte.
Das Research-Team von Noma Security setzte eine Organisation auf GitHub
auf, wie viele Teams es heute tun: eine Handvoll öffentlicher
Repositories, mehrere private und GitHub Agentic Workflows verdrahtet,
um die Routinearbeit zu erledigen. GitHub Agentic Workflows sind
Anweisungen in schlichtem Markdown, die GitHub Actions einem KI-Agent
übergibt, gestützt auf Claude oder Copilot, damit der Agent Issues
triagiert, Fragen beantwortet und Pull Requests im Namen des Teams
öffnet. Dann spielten die Forscher den Angreifer. Sie öffneten ein
gewöhnlich aussehendes Issue in einem der öffentlichen Repositories,
versteckten ein paar zusätzliche Sätze im Text und ließen den Workflow
laufen. Der Agent las das Issue, holte den Inhalt einer README.md aus
einem privaten Repository und fügte ihn in einen öffentlichen Kommentar
ein, wo jeder ihn lesen konnte.
Der Angreifer benutzte kein Passwort, keinen gestohlenen Schlüssel und keinen Exploit-Code, und es gibt keine CVE. Noma nennt die Technik GitLost, meldete sie an GitHub und veröffentlichte mit Wissen des Unternehmens. Der gesamte Payload war englische Prosa in einem Feld, für dessen Lektüre der Agent gebaut war.
Das Issue, das mit einem privaten Repo antwortete.
Die Mechanik ist kurz, und genau das macht sie es wert, sie zu zeichnen. Ein Workflow feuert bei einem Event, etwa wenn ein Issue geöffnet oder zugewiesen wird. Der Agent liest Titel und Text des Issues als seine Aufgabe. In diesem Text vergraben waren Anweisungen, die dem Agent sagten, die README eines privaten Repositorys zu holen und als Kommentar zu posten. GitHub hatte Guardrails davor: Sandboxing, Tokens, die standardmäßig read-only sind, Input-Bereinigung und einen Threat-Detection-Durchlauf über den Text. Noma probierte Varianten, bis eine durchrutschte. Der bösartigen Anfrage das Wort „Additionally“ (englisch für „außerdem“) voranzustellen war genug, um am Filter vorbeizukommen, weil das Modell sie als Folgeaufgabe las statt als Anfrage, die es ablehnen sollte. Eine Ein-Wort-Änderung trug die Injection über die Linie.
Umformulieren schlägt den Filter.
Ein Filter, der den Issue-Text liest und entscheidet, ob er einen Angriff enthält, rät Absicht aus Formulierung, und Formulierungen gibt es in endlosem Vorrat. Noma hat weder das Modell gebrochen noch einen Speicherfehler gefunden. Sie formulierten dieselbe Anfrage um, bis der Klassifikator sie unter seiner eigenen Schwelle einstufte, und „Additionally“ war die Formulierung, die saß.
Das ist die strukturelle Eigenschaft Tool-nutzender Agents, die wir letzte Woche aufgeschrieben haben: Ein Agent liest seine Anweisungen und die Daten, die er holt, als einen flachen Strom von Tokens, und er erschließt aus Ton und Position, welcher Teil ein Befehl ist, so wie ein Mensch überfliegt. Ein Issue-Text ist Daten. Injection ist der Zug, nicht vertrauenswürdige Daten wie einen Befehl zu formen und darauf zu wetten, dass das Modell danach handelt. Detection hilft und ist es wert, sie laufen zu lassen, und sie wird danebengehen: Ein Klassifikator hat eine Schwelle, und ein Angreifer mit unbegrenzten Versuchen probiert, bis eine Formulierung darunter liegt.
Die Lücke, die die Größe des Leaks bestimmte.
Ein Teil von GitLost überlebt jeden Filter, den GitHub als Nächstes ausliefert. Die Aufgabe des Workflows war, ein Issue in einem öffentlichen Repository zu triagieren. Der Token, den GitHub Actions in die Umgebung dieses Workflows legte, hatte Lesezugriff auf jedes öffentliche und private Repository der Organisation, weil Teams diese Breite gewähren, damit der Agent Kontext über Repos hinweg ziehen kann. Der Angreifer wählte das Ziel; der Scope des Tokens setzte die Grenze des Schadens. Formuliere den Angriff auf hundert Arten um, und diese Grenze bleibt dieselbe: was auch immer der Token sehen kann.
Nomas eigene Empfehlung zeigt auf dieselbe Naht. Ihr Rat an Verteidiger ist, den Token auf das eine Repository zu scopen, das der Workflow triagiert, statt auf die ganze Organisation. Dieser Rat räumt ein, dass die Injection manchmal landen wird, und dass der Blast-Radius dann die Größe der Aufgabe haben sollte statt die Größe des Accounts.
Der Exfil-Pfad war der Alltagsjob des Agents.
Die private README verließ die Organisation durch einen öffentlichen Kommentar, also etwas, das der Agent können soll. Issues zu kommentieren ist seine Funktion. Nichts auf der Leitung sah nach Diebstahl aus: kein seltsamer Endpunkt, kein kodierter Blob durch eine Seitentür. Ein Netzwerk-Monitor auf der Suche nach bösartigem Traffic hätte gesehen, wie der Agent einen Kommentar postet, was er den ganzen Tag tut. Wenn der Exfiltrationskanal eine sanktionierte Fähigkeit ist, ist die Verteidigung, die sich auszahlt, von vornherein einzugrenzen, was der Agent erreichen kann.
Wo du die Architektur ändern kannst.
Zwei Dinge an GitLost liegen außerhalb deiner Reichweite. Der Bug gehört GitHub, und GitHub arbeitet daran. Und der Agent lief auf GitHubs Servern, innerhalb von GitHub Actions, wo kein Produkt, das du installierst, im Pfad sitzt. Bromure Agentic Coding läuft auf dem Mac eines Entwicklers. Es steht nicht vor GitHubs serverseitigem Workflow und behauptet das auch nicht. Wenn deine einzige Exposition gegenüber dieser Problemklasse ein gehosteter Agent ist, den jemand anderes betreibt, ist der Hebel, den du hast, der, den Noma benannt hat: Scope den Token herunter.
Die übertragbare Lektion gilt der wachsenden Zahl von Teams, die Coding-Agents auf Maschinen betreiben, die sie kontrollieren, wo die Architektur deine Sache ist. Zwei Prinzipien tragen aus GitLost hinüber, und keines hängt davon ab, die Injection zu fangen. Halte die Umgebung dünn, damit ein gekaperter Agent wenig erbt, das sich zu nehmen lohnt. Scope das Credential auf die Aufgabe, damit die Reichweite einer Kompromittierung die Größe des Jobs hat statt die Größe des Accounts. Bromure Agentic Coding ist eine Anordnung dieser Prinzipien.
Bromure Agentic Coding führt deinen Coding-Agent,
Claude Code, Codex oder Grok, innerhalb einer wegwerfbaren Linux-VM pro
Profil aus: eigener Kernel, eigenes Dateisystem, eigener
Netzwerk-Stack, einen Hypervisor von deinem Mac entfernt, auf Apples
Virtualization-Framework. Ein Profil ist ein kohärenter Arbeitsbereich,
ein Kunde oder ein Service. Die echten Credentials betreten diese VM
nie. Bromure hält sie auf dem Host hinter einem Broker und liefert dem
Gast falsche Werte, die für die Tools, die sie lesen, echt aussehen;
ein Proxy auf deinem Mac tauscht den Stub auf der Leitung gegen das
echte Secret, wenn die Anfrage hinausgeht, und
die Sandbox, die den Schlüssel hielt
geht den Mechanismus durch. Ein Agent, der überredet wird, cat auf
eine Credential-Datei anzuwenden, findet einen Platzhalter, denn der
Wert, den er wollte, war nie auf seiner Seite der Grenze.
Der Token, den der Agent ausgeben darf, ist gescoped und läuft ab, sodass ein Leak eine schmale, zeitlich begrenzte Nutzung ist statt einer dauerhaften Berechtigung. Der ganze Arbeitsbereich ist eine VM, die verschwindet, wenn du die Session schließt. Lass die GitLost-Form durch diese Anordnung laufen, und die Injection kann immer noch landen, denn Isolation macht das Austricksen eines Modells nicht rückgängig. Ein Agent, der zur Exfiltration überredet wurde, greift nach einem Credential und findet einen Stub, gibt einen Token aus, der nur das eine Profil abdeckt, in dem er gearbeitet hat, und sitzt in einer Box ohne Pfad zum Rest deiner Maschine. Die Reichweite der Kompromittierung ist die Größe der Aufgabe.
Halte die Umgebung dünn
Ein gekaperter Agent kann nur aushändigen, was seine Umgebung hält. Stubs im Gast und echte Secrets auf dem Host bedeuten: Die Injection, die landet, findet Platzhalter, wo sie Schlüssel erwartet hat.
Scope das Credential auf die Aufgabe
Nomas Rat für GitHub-Workflows ist dasselbe Prinzip: Ein Token, der ein Repo abdeckt, deckelt den Schaden bei einem Repo. Scope und Ablauf verwandeln ein Leak in ein schmales, zeitlich begrenztes Ereignis.
Mach die Box wegwerfbar
Wenn der Arbeitsbereich eine VM ist, die beim Schließen verdampft, hat Persistenz keinen dauerhaften Platz, und der Blast-Radius endet mit der Session.
Geh davon aus, dass injiziert wird
Detection ist es wert, sie laufen zu lassen, und sie wird danebengehen. Designe so, dass das Ergebnis eines Fehlschlags überlebbar ist, statt darauf zu wetten, jede Formulierung zu fangen.
Was davon stehen bleibt.
Scoping macht einen Agent nicht sicher genug, um ihn auf ein echtes Secret zu richten. Legst du ein scharfes Credential in die VM und der Agent wird überredet, es zu lesen, macht kein Hypervisor das Lesen rückgängig; die Änderung liegt darin, was der Agent erreichen kann, nicht darin, ob ein ausgetrickstes Modell ausgetrickst bleibt. Das Exfil-Problem, das Noma hervorgehoben hat, hat ein Stück, das Isolation allein ebenfalls nicht schließt: Ein Agent, der einen Kommentar posten, einen PR öffnen oder eine Nachricht senden kann, kann Daten durch diesen sanktionierten Kanal hinausbewegen, und Scoping entscheidet, wie viele Daten in Reichweite liegen, um bewegt zu werden, nicht, ob der Kanal existiert. Und GitLost selbst gehört GitHub. Update, wenn sie patchen, und scope deine Workflow-Tokens in der Zwischenzeit herunter, denn das ist der Hebel, den die Plattform dir reicht.
Wo auch immer du einen Agent laufen lässt, Forscher werden weiter Injections melden, und der Scope des Credentials in der Umgebung des Agents wird weiter darüber entscheiden, ob jede einzelne als geloggter Beinahe-Treffer endet oder als privates Repository auf einer öffentlichen Seite. Nomas Fix und Bromures Architektur zeigen in dieselbe Richtung: Gib dem Agent die Reichweite, die die Aufgabe braucht, und nichts darüber hinaus.
Bromure Agentic Coding führt Claude Code, Codex und Grok in wegwerfbaren Linux-VMs auf Apple Silicon aus, mit den echten Credentials auf dem Host hinter einem Broker, eingetauscht auf der Leitung, Prompt-Injection-Erkennung auf den Eingaben des Agents und jedem Aufruf geschrieben in einen Trace, den der Agent nicht editieren kann. Es ist kostenlos, Open Source und heute verfügbar auf bromure.io. Mit Dank an Noma Security, deren GitLost-Write-up diesen Beitrag angestoßen hat.