Die Registry reichte Zettel zwischen Sandboxes weiter
Check Point hat am 8. September eine Untersuchung veröffentlicht, die zeigt: Zwei Code-Ausführungscontainer von ChatGPT, betrieben unter zwei verschiedenen Konten und ohne Netzwerkpfad zueinander, konnten sich über die interne JFrog-Artifactory-Instanz, die sie mit Paketen versorgte, Daten zuschieben. An der Vordertür brach nichts. Das Leser-Credential dieser Container durfte auch schreiben, also diente ein Metadatenfeld an einem gespeicherten Paket als Postfach. Bromure Agentic Coding gibt dem Gast kein Konto auf dem Spiegel und lässt Sie read-only in eine Regel schreiben, die der Draht durchsetzt.
Die Isolation hielt, die Konnektoren verhielten sich wie dokumentiert, und der Dienst in der Mitte war überhaupt erst aus Sicherheitsgründen installiert worden. Die Post des Opfers erreichte trotzdem das Konto eines Fremden – über ein Metadatenfeld an einem gespeicherten Paket.
Im Juni schrieben Forscher von Check Point eine Eigenschaft an eine Datei in einem
Paket-Repository. Die Eigenschaft hieß chatgpt_test_ts, ihr Wert war ein
Zeitstempel. Geschrieben haben sie sie aus dem Inneren der Sandbox, die den Code
für eine ChatGPT-Unterhaltung ausführt. Dann öffneten sie eine Unterhaltung unter
einem anderen Konto, in dessen eigenem Container, und lasen dieselbe Eigenschaft
zurück. Der Wert kam unversehrt an.
Dieser Zeitstempel ist der ganze Befund. Check Point hat ihn am 8. September veröffentlicht unter einem Titel, der jede Zusammenfassung schlägt: The Shared Clipboard Inside the Sandbox. OpenAI hatte den Dienst bis dahin abgeschaltet. Die Forscher hatten Ende Juni gemeldet und erfuhren, die interne Artifactory-Instanz sei außer Betrieb genommen worden – es gibt also keinen Patch anzuwenden und für Nutzer nichts zu tun. Die Form davon bleibt.
Der Dienst in der Mitte
Eine ChatGPT-Unterhaltung, die Code ausführt, bekommt ihren eigenen Container,
isoliert von den Containern anderer Unterhaltungen. Dieser Teil funktionierte. Ein
Container, der Python ausführt, braucht auch pip install, und ein umsichtiges
Plattformteam lässt eine Sandbox nicht selbst zu pypi.org hinaus. Also bekommt
die Sandbox einen kontrollierten Vermittler: eine interne
JFrog-Artifactory-Instanz, die sich vor die
öffentlichen Registries setzt und geprüfte Pakete nach innen ausliefert.
Das ist gutes Design. Eine Bank stellt dasselbe vor npm, ein reguliertes Gesundheitsunternehmen stellt es vor PyPI. Der Spiegel existiert, um die Exposition der Sandbox zu verringern, und genau das tut er.
Er gibt jedem Container außerdem ein Konto auf dem Spiegel.
Die REST-API von Artifactory enthält eine Gruppe Item Management, erreichbar unter
/api/storage/{repoKey}/{itemPath}, mit der ein Client beliebige benannte
String-Eigenschaften an ein gespeichertes Objekt anhängen und wieder auslesen
kann: Set Item Properties und Get Storage Item Information. Das Setzen
einer Eigenschaft verlangt die Berechtigung Annotate. Das Lesen nicht. Check
Point fand heraus, dass das an die Sandbox-Container ausgegebene Credential, als
Leser gedacht, beides trug. Wie
Cybersecurity News es zusammenfasste,
hatten „die den Containern übergebenen Leser-Credentials genug Rechte, um diese
Eigenschaften sowohl zu schreiben als auch zu lesen“, und „diese Eigenschaften
waren nicht pro Konto isoliert“.
Eigenschaftswerte nehmen Text auf, oder Base64 für alles Binäre, und eine Nutzlast, die für eine Eigenschaft zu groß ist, verteilt sich über mehrere und wird auf der anderen Seite wieder zusammengesetzt. Zwei Container, die zueinander beziehungslosen Kunden gehören und keinen Netzwerkpfad zwischen sich haben, verfügen damit über einen bidirektionalen Kanal mit einer Bandbreitengrenze, die keine Erwähnung wert ist.
Zwei Unterhaltungen im selben Zug
Die Anweisungen des Angreifers erreichen das Opfer auf gewöhnlichen Wegen: ein eingefügter Prompt, ein geteilter Unterhaltungslink oder ein Custom GPT, dessen Builder-Anweisungen der Nutzer nicht sieht. Das Opfer schickt dann eine normale Nachricht, und das ist der ganze Auslöser.
Im Thinking-Modus verarbeitete das Modell zwei unabhängige Arbeitsströme in einem Zug. Im Proof of Concept von Check Point stellte das Opfer eine Kochfrage und bekam eine korrekte Antwort darauf, während das Modell neben dieser Antwort das verbundene Gmail-Konto des Opfers las und das Gefundene in eine Artifactory-Eigenschaft schrieb, die der Container des Angreifers abholen konnte. Pedro Drimel Neto, der bei Check Point das Malware-Analyseteam leitet, sagte The Register: „Eine präparierte Anweisung konnte ChatGPT dazu bringen, neben der sichtbaren Unterhaltung einen zweiten Aufgabenstrom zu verarbeiten.“ Gmail war die Demonstration. Google Drive, Microsoft Teams und GitHub lagen in derselben Reichweite.
Das Opfer sah ein einziges Signal, ein kleines Label „Talked to Gmail“, und es erschien im Nachhinein. Konnektoren stehen standardmäßig auf der Einstellung Important actions, die Lesezugriffe mit geringem Risiko ohne Rückfrage genehmigt; das strengere Always ask hätte eine Rückfrage erzeugt. Diese Einstellung klassifiziert einen Mail-Lesezugriff als geringes Risiko, ohne zu fragen, wer ihn angefordert hat.
Check Points Beschreibung des Modells: Es „kann daher als genötigter Insider handeln: nicht bösartig, aber überredet, im Auftrag des Angreifers zu handeln“.
Der Teil, der sich verallgemeinert
Streichen Sie ChatGPT heraus, und die Geschichte handelt von einem Coding-Agenten, denn die Struktur ist identisch.
Eine Agenten-Sandbox muss Pakete installieren. Sie unvermittelt an die
öffentlichen Registries zu lassen, war genau das, was Sie vermeiden wollten, also
stellen Sie einen Spiegel davor: Artifactory, Nexus, einen privaten npm-Proxy, was
auch immer Ihre Organisation standardisiert hat. Die Sandbox authentisiert sich
jetzt an diesem Spiegel, hält also ein Credential, und irgendwer hat lange vor der
Existenz dieses Agenten entschieden, was dieses Credential darf.
Paket-Registries nehmen Uploads, Tags, Annotationen und Aufbewahrungsregeln an, und
das macht Annotate zu einer kleinen Berechtigung auf einer weiten Fläche.
Fragen Sie Ihr eigenes Setup deshalb zwei Dinge, statt zu fragen, ob die Sandbox isoliert ist. Benennen Sie, worauf sie ein Konto hält. Dann benennen Sie, welche Verben auf diesem Konto funktionieren.
In einem Bromure-Workspace
Bromure Agentic Coding führt jeden Coding-Agenten in einer hardwarevirtualisierten Linux-VM auf Ihrem Mac aus und hält die echten Geheimnisse auf der Host-Seite dieser Linie. Führen Sie Check Points drei Zutaten durch einen Workspace.
Ein gemeinsamer Dienst. Es gibt keinen. Jeder Workspace entspricht einer VM, mit eigener Systemplatte, eigenem Home-Image, eigener IP und eigenem MITM-Proxy-Listener auf dem Host. Zwei Workspaces teilen keine VM, und das Handbuch beschreibt ein Paar von ihnen so, dass sie „niemals ein Byte teilen“. Unter den Workspaces liegt kein flottenweiter Spiegel mit einer Metadatenebene, in die beide schreiben können. Was unter einem Workspace liegt, ist ein Prozess auf Ihrem eigenen Mac, einer pro Workspace.
Ein Credential auf dem Spiegel. Der Agent hält keines. Paketinstallationen in
einem Bromure-Workspace verlassen ihn über einen Virtio-Socket zum Host-Proxy, und
der Proxy spricht mit der Registry. Bromure hält die API-Schlüssel der
Reputationsdienste hostseitig und exportiert sie in keine VM. Der Depi-Pfad ist der
klarste Fall: Der Proxy hängt Ihren Registry-Schlüssel auf dem Host als
Authorization: Bearer-Header an und entfernt im Vorbeigehen jeden
Authorization-Header, den der Gast gesendet hat. Im Gast existiert kein
Leser-Credential, also kann keines ein Verb zu viel tragen.
Ein Schreibverb, das seinen Grund überlebt hat. Hier dürfen Sie die
Einschränkung selbst hinschreiben. Das Guardrails-Panel eines Workspace trägt eine
geordnete Egress-Firewall, und Regeln für das Protokoll web nehmen eine Spalte
Methods auf. Unter allow bilden die Methoden eine Erlaubnisliste, und
read-only ist die Kurzform für GET, HEAD und OPTIONS. Das Handbuch sagt, warum
die Spalte existiert: Die Methodendimension „ist das, was einen Workspace eine API
lesen lässt, die er nicht schreiben darf“ – am Draht, unabhängig davon, welches
Werkzeug in der VM die Anfrage stellt. Zwei Schichten setzen das durch. Der
virtuelle Netzwerk-Switch gleicht jeden Fluss über Ziel-IP und per DNS
mitgeschnittenen Hostnamen ab, und der Proxy gleicht erneut über TLS-Servername und
einzelne HTTP-Methode ab, sodass ein kompromittierter Agent keinen Weg um eines von
beiden herum hat. Änderungen erreichen laufende Sitzungen ohne Neustart, und jedes
Urteil landet als Firewall-Zeile in der Security Timeline.
Der zweite Strom, und der Weg zurück nach draußen
Der zweite Aufgabenstrom des Angreifers kam als Inhalt an, den das Modell las. In
einem Bromure-Workspace reist alles, was ein Agent aufnimmt und an das Modell
zurückstreamt (Dateiinhalte, Webseiten, Kommandoausgaben, alles, was ein Werkzeug
zurückgibt), als tool_result-Spans durch denselben Host-Proxy. Der
Quellcode-Detektor bewertet diese Spans mit einem lokalen PromptGuard-Klassifikator,
bevor das Modell darauf reagiert, und protokolliert dann den Treffer, pausiert für
Ihre Entscheidung oder blockiert die Anfrage. Der Detektor wird abgeschaltet
ausgeliefert und lädt beim ersten Aktivieren ein 298 MB großes Modell herunter –
aktivieren Sie ihn also vor der Sitzung, in der Sie ihn brauchen.
Der ungenehmigte Konnektor-Lesezugriff hat hier sein Gegenstück. Die
MCP-Bearer-Token eines Bromure-Workspace erscheinen in der VM als
brm-mcp_-Platzhalter. Das echte Token bleibt außerhalb des Gastes, und der Proxy
setzt es am Draht in Richtung des einen Hosts ein, für den es ausgestellt wurde.
Schalten Sie Ask before use für ein Credential ein, und dessen erste Nutzung in
einer Sitzung pausiert für einen hostseitigen Dialog, der eine Freigabe für 5
Minuten, 1 Stunde oder den Rest der Sitzung anbietet. Das ist die Rückfrage, die
„Important actions“ nicht anzeigen wollte – pro Credential, auf der Maschine, an
der Sie sitzen.
Sollte etwas in der VM einen Platzhalter irgendwohin tragen, wo er nicht
hingehört, verweigert der Proxy die Anfrage, ohne ein Byte weiterzuleiten,
pausiert die VM und löst einen Alarm aus, der die Token-Vorschau, das Credential,
den Host, für den es ausgestellt wurde, und den Host, zu dem es unterwegs war,
benennt. Unter diesem Stolperdraht schreibt Tracing auf Activity only eine
Metadatenzeile pro Anfrage: Host, Methode, Pfad, Status, Bytes, welche Credentials
der Proxy getauscht hat, und eine Leck-Warnung für jedes bearer-artige Token, das
Bromure nicht ausgestellt hat. Führen Sie nach einer Sitzung
bromure-cli trace hostnames aus, und jeder einzelne Host, den der Agent
kontaktiert hat, wird mit einer Zählung ausgegeben.
Wenn Sie einen Spiegel für Ihre Agenten betreiben
Prüfen Sie die Identität, mit der sich Ihre Sandboxes authentisieren, noch vor
dem Netzwerkpfad zwischen ihnen. Suchen Sie in Artifactory nach Annotate an
einem Token, das Sie für einen Leser halten, und nach einem Permission Target,
das breiter ist als die Repositories, aus denen die Sandbox installiert. Die
Property-API ist eine schreibbare Metadatenebene; Aufbewahrungsregeln, Tags und
Build-Infos sind weitere. Ein Leser, der annotieren kann, kann posten.
Die Regel, die das in einer Zeile beantwortet
Fügen Sie im Guardrails-Panel des Workspace eine Egress-Regel für die
Registry mit dem Protokoll web und read-only in der Spalte Methods hinzu,
setzen Sie dann Unmatched traffic auf Deny und listen Sie auf, was die
Arbeit braucht. Die pf-Ausgabe am unteren Rand des Panels druckt, was Sie gebaut
haben: allow web registry.npmjs.org read-only, allow web api.github.com,
default deny. Sie gilt für laufende Sitzungen ohne Neustart.
Ein gemeinsamer Dienst macht Mandanten zu Nachbarn
Der Instinkt nach einer Geschichte wie dieser ist, die Wände zu prüfen. Die Wände waren in Ordnung. Zwei Container unter zwei Konten hatten keinen Weg zueinander, und Check Point fand keinen. Sie fanden einen Dritten, mit dem beide Container sprechen durften, und nutzten ihn so, wie Menschen seit dreißig Jahren gemeinsame Laufwerke und DNS-TXT-Records nutzen.
Check Point formuliert die Lehre im Papier: „Ein gemeinsam genutzter interner Dienst, rein als Infrastruktur gedacht, kann zu einer unbeabsichtigten Kommunikationsschicht zwischen Umgebungen werden, die isoliert bleiben sollten.“ Infrastruktur, die Sie aus Sicherheitsgründen installieren, ist immer noch Infrastruktur, und ihre Mandanten sitzen einen Hop voneinander entfernt. Verkleinern Sie die Menge der Dinge, auf denen eine Sandbox ein Konto hält, und verlagern Sie die Entscheidung darüber, was diese Konten dürfen, auf jede einzelne Anfrage – heraus aus einem Provisionierungsticket, das jemand vor zwei Jahren geschlossen hat.
Eine Agenten-Sandbox, die es wert ist, betrieben zu werden, wird einen kontrollierten Weg zu den Paketen haben, die sie braucht, denn die Alternative ist schlimmer. Behandeln Sie diesen Weg als Beziehung mit angehängten Berechtigungen, und behandeln Sie diese Berechtigungen als Ihren Perimeter. Entscheiden Sie sie dort, wo Sie sie noch sehen können. Installieren Sie Bromure Agentic Coding und geben Sie Ihrem Agenten nichts, womit er sich anmelden könnte.