Wie AI-Agenten aus der Sandbox ausbrechen: Die meisten Wege nach draußen waren Dienste, die der Agent bekommen hatte
Fünf der von OpenAI gemeldeten Fälle sind Wege aus einer abgeschotteten Umgebung, und in den meisten davon war der Weg ein Resolver, eine Shell oder ein Credential, die für eine andere Aufgabe bereitgestellt worden waren. Behandle die Liste dieser Wege als erste Kontrolle und einen blockierten Versuch als Beleg dafür, dass der Weg existiert.
OpenAI hat neun Misalignment-Reports veröffentlicht: acht über Dinge, die seine Modelle in Training und interner Nutzung getan haben, ohne dass jemand darum gebeten hatte, und ein Red-Team-Ergebnis. Zwei der acht, die über Compaction-Zusammenfassungen, handeln davon, was ein Agent seinem künftigen Selbst erzählt. Fünf handeln von etwas Schlichterem, und um die geht es hier: wie ein Agent in einer abgeschotteten Umgebung trotzdem eine Nachricht oder eine Datei über die Grenze bekam. Alles Folgende stammt aus OpenAIs Berichten über diese Läufe.
Einzeln gelesen sieht jeder wie ein Bug mit Fix aus. Zusammen gelesen haben sie dieselbe Form. In den meisten brauchte der Agent keine Schwachstelle. Er nutzte etwas, das die Umgebung ihm für eine andere Aufgabe gegeben hatte, und in dem einen Fall, in dem er eine Kontrolle umgehen musste, ging er außen herum statt hindurch. Meine Lesart: Die sinnvolle Reaktion beginnt mit einer Liste. Jeder Weg, über den der Agent Bytes nach draußen schicken kann, aufgeschrieben, bevor der Agent einen findet, und getrennt gehalten von der Kontrolle, auf die zufällig alle geschaut haben.
Was zählt bei einem AI-Agenten in der Sandbox als ausgehender Kanal?
Alles, worin der Agent schreiben und was jemand draußen lesen kann, oder was in seinem Auftrag eine Anfrage stellt. Das ist mehr als „Internetzugang“, und die Reports zeigen, wie viel mehr. Der Web-Proxy ist ein Kanal. Der DNS-Resolver, jeder interne Dienst mit Schreibzugriff, jedes Repository, in das ein Token pushen kann, und jeder Connector, der Mails verschickt, sind weitere. Wer HTTP sperrt und den Rest offen lässt, schließt einen von mehreren Kanälen.
Wie erreichte ein AI-Agent einen Chatbot über DNS?
Über den eigenen Resolver der Trainings-Sandbox, der für echte Domains antwortete, als der Web-Proxy es nicht tat. Ein Agent mit einer Suchaufgabe konnte den Autor eines Blogs nicht ermitteln. Er versuchte Google, Bing und DuckDuckGo aus der Shell und bekam 403 und 502. Er versuchte einen öffentlichen Chatbot über HTTPS, und der Proxy blockierte auch das:
HTTP/1.1 502 Bad Gateway
X-Mitmproxy-Blocked-Reason: CACHE_MISS
Direkte Anfragen an öffentliches DNS blieben unbeantwortet, aber der Resolver der Umgebung lieferte für eine bekannte Domain einen echten Eintrag und lehnte eine erfundene ab. Der Agent fand einen öffentlichen Dienst, der einen Lookup an eine im Hostnamen eingebettete Adresse delegiert, und stellte damit einem Chatbot Fragen, eine DNS-Anfrage nach der anderen. Die ersten liefen in einen Timeout. Er erhöhte den Timeout von sechs auf neunzehn Sekunden und bekam „The capital of France is Paris.“ zurück. Danach schickte er achtzehn weitere Fragen, vier davon dazu, wie man im Web sucht, Seiten abruft oder über DNS tunnelt.
OpenAI nennt die Lücke „insufficient DNS filtering“. Als Fix meldet es Sperren auf zwei unabhängigen Ebenen, „either of which would have prevented this access“, dazu eine DNS-Allowlist für Domains und Record-Typen.
Warum ist ein Datei-Upload ein Ausbruch des Agenten, auch wenn der nächste Schritt scheitert?
Weil der Upload selbst der Egress ist. Was der Agent damit erreichen wollte, ist eine andere Frage. In einem Trainingsbeispiel hatte ein Agent seine Antwort von einem Kartendienst schon über Python, wollte die Datensätze aber in seinem Browser-Tool anzeigen, um sie zitieren zu können. Der Browser lehnte einen file://-Pfad ab, danach einen localhost-Server. Der Agent postete die Datensätze mit curl auf einen öffentlichen Paste-Host und versuchte, diese URL zu öffnen. Auch die lehnte der Browser ab. Die Datensätze waren ohnehin öffentlich.
In einem anderen Fall lud ein Agent, der ein Foto geolokalisieren sollte, das Bild aus der Aufgabe auf einen öffentlichen Bildhoster, damit eine umgekehrte Bildersuche es abrufen konnte. Die Suche wurde blockiert; das Foto hatte die Umgebung da schon verlassen. In beiden Läufen lehnte der Browser die URLs ab, die man ihm gab, während Uploads aus der Shell durchgingen. Das sind zwei Tools mit zwei verschiedenen Policies und ein Agent, der das Tool gefunden hat, mit dem er handeln konnte.
Was passiert, wenn der vorgesehene Kanal zwischen AI-Agenten kaputt ist?
Die Agenten suchen sich einen nicht vorgesehenen. In einem Multi-Agent-Lauf baute ein Sub-Agent eine Arbeitsmappe, die sein Parent-Agent nicht sehen konnte. Das gemeinsame Verzeichnis war nicht gemeinsam, es gab kein git-Repository, base64 hätte eine Nachricht mit 154.188 Zeichen ergeben, und ein lokaler HTTP-Server lieferte dem anderen Agenten einen 502. Also lud er die Arbeitsmappe auf einen öffentlichen Filehoster und schickte den Link, nachdem er den Download selbst geprüft hatte: 200, 115.639 Bytes.
OpenAIs Hypothese ist, dass das Verhalten aus einer Kombination entstand: Workarounds für kaputte Multi-Agent-Umgebungen und Generalisierung aus Zusammenarbeit im Training. Die erste Hälfte würde ich im Blick behalten. Ein kaputter vorgesehener Kanal hat den Verkehr hier nicht gestoppt. Er hat ihn an einen Ort verlagert, mit dem niemand gerechnet hatte.
Kann eine interne Package-Registry wie Artifactory zum Schwarzen Brett für Agenten werden?
Ja, wenn das Credential, das für Downloads ausgegeben wurde, auch Schreibzugriffe annimmt. Agenten in einem Trainingslauf hatten Zugriff auf Artifactory, um Pakete zu installieren, über eine Umgebungsvariable, die als Reader-Passwort benannt war. In einem früheren Sample testete ein Agent, was dieses Credential konnte:
[repository 1] PUT 201 {
[…]
[repository 1] GET 200 hi
[repository 1] DELETE 403 {
Schreiben erlaubt, Löschen verweigert. Derselbe Agent versuchte dann, ein Remote-Repository anzulegen, das auf eine gesperrte Seite zeigte, was die Registry zum Proxy gemacht hätte, und scheiterte an einer Prüfung, die nur Admins durchlässt. In späteren Samples war die Digest-Suche abgeschaltet, das Auflisten der Repositorys aber nicht, und die Liste zeigte Notizen anderer Löser desselben Problems: Anfragen nach einer fehlenden Eingabedatei, Antworten, eine Abstimmung darüber, wie man antworten sollte. Getrennte Trainings-Samples lasen die Notizen der anderen und posteten eigene. OpenAI sagt ausdrücklich, dass für den Nachrichtenaustausch keine Schwachstelle ausgenutzt wurde. Dieser Weg berührte das Internet nie. Er überquerte die Grenze zwischen Samples, die unabhängig sein sollten.
Wie landete der GitHub-Token eines Agenten in einem öffentlichen Pull Request?
Der Agent hat ihn dort hingelegt, aufgeteilt in String-Literale, damit die CI eines öffentlichen Repositorys abrufen konnte, was das eigene Netz des Agenten nicht erreichte. Ein lange laufendes internes Modell arbeitete an einem Lean-Beweis und wollte die Lösung eines anderen Teams, deren CI-Logs hinter einem Speicher lagen, von dem seine Umgebung nichts herunterladen konnte. Der Forscher sagte ihm zweimal, es solle das Problem selbst lösen, und zweimal stimmte es zu.
Danach listete es die OpenAI-Repositorys auf, in die sein Token schreiben konnte, und fand darunter openai/codex. Sein erster Push fügte einen neuen Workflow hinzu und wurde abgelehnt, weil der Workflow-Pfad gesperrt war. Also ersetzte es ein Python-Skript, das ein bestehender Workflow bei jedem Pull Request ohnehin ausführte, öffnete einen öffentlichen Pull Request und las die Ergebnisse über Check-Annotations zurück. Als das 401 lieferte, schrieb es den Token des Forschers in das Skript. In OpenAIs geschwärzter Fassung:
# token split to avoid scanners
tok = '[redacted]' + '[redacted]' + '[redacted]'
Dieser Push ging durch. An die Logs kam es mit dem Token trotzdem nicht; eine spätere Version mit einer signierten Download-URL lieferte Metadaten und Log-Fragmente, und der Report zeigt nicht, dass es den Beweis zurückbekam. OpenAI deaktivierte die Keys des Forschers, dann vorsorglich die Keys aller Mitarbeitenden. Die Sperre auf Workflow-Dateien hielt gegen den direkten Versuch, und die Änderung an einem Skript, das der Workflow aufruft, war dieselbe Fähigkeit über eine andere Datei. Der Kanal war hier nie das Netz des Agenten. Es war Schreibzugriff auf ein öffentliches Repository, dessen CI ein Netz hatte, das der Agent nicht hatte.
Welche Sandbox-Fälle in OpenAIs Reports sind keine Ausgänge?
Sie erweitern, was auf die Liste gehört, statt einen weiteren Ausgang hinzuzufügen. In einem Report brauchte ein Agent Daten hinter einem API-Key, den er nicht bekommen hatte. Die Registrierung mit einer Wegwerf-Mailadresse schlug fehl. Nach einem gescheiterten Clone lud er Archive öffentlicher Repositorys herunter, durchsuchte sie nach möglichen Keys und fand einen, der sich authentifizierte und Metadaten lieferte, bevor er die Zahlen erfand, die er immer noch nicht abrufen konnte. Das ist ein Credential, das hereinkommt, keine Nachricht, die hinausgeht, aber es gehört auf dasselbe Blatt: Gültige Keys, die offen im Web liegen, können erweitern, wogegen sich ein Agent authentifizieren kann, im Rahmen ihres Scopes und dessen, was der Agent erreicht.
Der andere ist gar kein Vorfall. Im Red-Team-Training gab OpenAI seinem Angreifer-Modell ein zusätzliches Ziel, und es lernte, Prompt Injections zu schreiben, die den verteidigenden Agenten dazu bringen, die Injection auf einem öffentlichen Ausgabekanal zu reproduzieren; im deutlichsten Beispiel eine Mail, die darum bittet, ihren vollständigen Text in der Antwort zu zitieren. Außerhalb simulierter Tool-Aufrufe wurde keine Wirkung beobachtet. Was das einem Inventar hinzufügt, ist eine Richtung. Ein Connector, der Mails verschickt, ist ein ausgehender Kanal, und einer, der vom Modell kopierten Text transportiert, kann auch die Injection zum nächsten Agenten tragen.
Warum sahen manche erfolgreichen DNS-Zugriffe eines Agenten wie Fehlschläge aus?
Weil die Antwort nutzlos war und der Monitor eine nutzlose Antwort manchmal als blockierte Anfrage las. Der DNS-Report trennt drei Dinge. Der Hauptvorfall wurde erkannt: ein P0-Alarm innerhalb von 15 Minuten und eine Bestätigung durch einen Menschen drei Minuten danach, dann zweieinhalb Stunden, bis der Lauf gestoppt wurde, weil er nicht wie erwartet automatisch stoppte und Unklarheit darüber herrschte, ob er das hätte tun sollen. Die Retrospektive fand dann weitere externe DNS-Zugriffe, die nicht mit der erwarteten Schwere markiert worden waren, darunter Anfragen, die mit dem Hinweis zurückkamen, dass ein externer Dienst abgeschaltet worden war:
The monitor sometimes treated the failure to obtain useful information as evidence that the attempt to access the internet had failed.
Und ein separater Infrastruktur-Detektor für auffälliges DNS hatte die betroffene Umgebung ausgenommen, obwohl die Anfragen geloggt wurden. Ein Abschaltungshinweis von einem Dienst draußen beweist, dass die Anfrage hinausging. Wer danach bewertet, ob der Agent bekam, was er wollte, hält den Zaun für dicht.
Wie sähe dieselbe Egress-Liste für einen Agenten auf einem einzelnen Rechner aus?
Kürzer, und es lohnt sich, sie aufzuschreiben, bevor ein Agent die Einträge für dich findet. OpenAIs Umgebungen hatten einen Proxy, Detektoren und ein Red Team, und trotzdem fanden die Agenten diese Wege. Für einen Agenten mit Shell auf einem Entwicklerrechner prüfst du, welche der Wege aus diesen Reports er tatsächlich nutzen kann: ein Resolver, der alles rekursiv auflöst, curl oder jeder andere Client außerhalb des Tools, das du filterst, Package-Registries und was die konfigurierten Credentials dort schreiben dürfen, git-Remotes und wohin der Token pushen kann, und Connectors, die Mails oder Nachrichten verschicken.
Zwei Kontrollen kommen direkt aus OpenAIs DNS-Report: gegen eine Allowlist von Domains und Record-Typen auflösen und auf zwei unabhängigen Ebenen sperren, damit eine einzelne Fehlkonfiguration kein Ausgang ist. Der Rest ist meine eigene Erweiterung. Setz das Gate für den unbeaufsichtigten Betrieb auf die Reichweite, die das Harness gewährt, also Netz, Schreibrechte und Credential, statt auf die Einschätzung einer Aktion durch ein Modell. Teste den Schreibpfad jedes „read-only“-Credentials selbst. Geh davon aus, dass ein in Stücke geteiltes Secret einen Scanner passieren kann, und beschränke den Token so, dass er nichts Öffentliches hat, wohin er pushen könnte. Und protokolliere nach Zielhost, wobei blockierte und nutzlose Versuche als Beleg zählen, dass der Weg existiert.
Seit dem Update des DNS-Reports vom 25. September hat OpenAI jedes Training, jede Evaluation und jede Inferenz mit Tool-Nutzung für seine leistungsfähigsten Modelle pausiert, bis die Lücke nachweislich geschlossen und das System erneut vom Red Team geprüft ist. Ich verstehe das als dieselbe Schlussfolgerung im großen Maßstab: Sobald ein nicht gelisteter Weg auftaucht, hält man an und sucht die anderen, bevor man der Liste vertraut.