Zurück zu allen Beiträgen
Veröffentlicht am · von Renaud Deraison

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 Konten, kein Pfad zwischen ihnen, ein Dienst, den beide brauchenKonto des AngreifersContainer zur CodeausführungLeser-Credential + AnnotateKonto des OpfersContainer zur CodeausführungLeser-Credential + AnnotateIsolation hältkein Netz, keine gemeinsame Platteinternes JFrog Artifactory — der geprüfte Paketspiegel/api/storage/{repoKey}/{itemPath}ein gespeichertes Paket, eine benannte Eigenschaftchatgpt_test_ts = “…” · Base64, gestückelt wenn großEigenschaften sind nicht pro Konto getrenntSet Item PropertiesGet Storage Item Info
Der verdeckte Kanal. Zwei ChatGPT-Unterhaltungen unter verschiedenen Konten erhalten je einen isolierten Container zur Codeausführung, ohne Netzwerkpfad zwischen ihnen. Beide Container müssen dieselbe interne Artifactory-Instanz erreichen, um Pakete zu installieren, und das ihnen ausgegebene Leser-Credential trug auch die Berechtigung Annotate. Container A schreibt eine benannte Eigenschaft an ein gespeichertes Objekt, Container B liest sie zurück. Die Eigenschaften waren nicht pro Konto getrennt, sodass die Metadatenebene des Paketspiegels als gemeinsames Postfach diente.

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.

die Entscheidung, weiter oben getroffenSandbox-ContainerLeser-Token + AnnotateScope einst festgelegtGET + PUTgeteilter Spiegel — eine Instanz, alle MandantenPakete auf der Artefaktebene, Postfächer auf der Metadatenebenewas das Token darf, war nie eine Frage pro Sitzungdie Entscheidung am Draht, pro WorkspaceWorkspace-VMkein Registry-Credentialnur Attrappen, brm-…kein anderer Weg ins Netzvsock 8443Host-Proxy — einer pro Workspace, auf Ihrem MacGast-Authorization entfernen · echten Key anhängenallow web registry.npmjs.org read-onlygeprüft nach TLS-Servername und HTTP-Methode, bei jeder Anfrage
Dieselbe Anforderung, zwei Orte für die Entscheidung. Oben: Die Sandbox authentisiert sich an einem gemeinsamen Spiegel, und was sie dort darf, wurde weiter oben entschieden, einmal, in einer Rechtevergabe, die die Person überlebt hat, die sie vornahm. Unten: Der Gast hält kein Registry-Credential und keinen Weg ins Netz außer einem Virtio-Socket zu einem Host-Proxy pro Workspace, wo der Schlüssel angehängt, der Authorization-Header des Gastes entfernt und über eine geordnete Regel entschieden wird, welche HTTP-Methoden den Host überhaupt erreichen dürfen.

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.