Der freie Platz war nicht leer
Am 24. September haben Cloudflare und Oren Yomtov von Accomplish eine mandantenübergreifende Lücke in Cloudflare Containers und Sandboxes veröffentlicht. Schreiben Sie 4 KiB in eine frische Sandbox, lesen Sie die rohe Platte, und die anderen 60 KiB des Blocks kommen zurück und enthalten die .env-Dateien, Zugangsdaten-Dateien und Chromium-Profile des vorherigen Mandanten. Nichts ist aus irgendetwas ausgebrochen: jede aktive Grenze hielt, und das Leck lag darin, was mit einem Block geschah, nachdem sein Besitzer mit ihm fertig war. Cloudflare verkauft Sandboxes, um Code auszuführen, den Sprachmodelle erzeugt haben. Bromure Agentic Coding führt diesen Code aus einer Image-Datei auf Ihrem eigenen Mac aus, und die freien Blöcke, aus denen es schöpft, sind Ihre.
Eine Sandbox hat zwei Aufgaben. Einzuschließen, was darin läuft, und zu vergessen, was darin vorher lief. Die zweite ist eine Konfigurationsoption.
Sie schicken die Testsuite des Agenten in eine Cloud-Sandbox, weil es irgendwann im
letzten Jahr aufgehört hat, clever zu wirken, ungeprüften Code auf dem eigenen
Laptop laufen zu lassen. Die Sandbox steht in etwa einer Sekunde mit einem
vollständigen Linux-Dateisystem. Der Agent schreibt eine kleine Datei. Darunter
reicht die Plattform ihm einen Plattenblock von 64 Kilobyte, und 60 dieser Kilobyte
enthalten noch die .env von jemand anderem.
Sie mussten aus nichts ausbrechen, um dorthin zu kommen.
Schreiben Sie vier Kilobyte, lesen Sie sechzig
Am 24. September hat Cloudflare einen gemeinsamen Bericht mit den Forschern über eine mandantenübergreifende Lücke in Cloudflare Containers veröffentlicht. Oren Yomtov von Accomplish hat sie am 4. September über HackerOne gemeldet und seine eigene Darstellung veröffentlicht, in derselben Woche. The Hacker News berichtete am Tag darauf.
Containers gibt jedem Kunden eine Platte aus einem gemeinsamen Pool, über Linux
Device-Mapper Thin Provisioning, mit einer Blockgröße von 64 KiB. Der Pool trug die
Option skip_block_zeroing, die genau das tut, was sie sagt: dm-thin löschte einen
neu zugewiesenen Block nicht, bevor es ihn an einen Container übergab. Wurde ein
Container gelöscht, gingen seine Blöcke mit unverändertem Inhalt in den Pool
zurück, und der Pool spannte sich über Kundenkonten hinweg.
Von dort sind es vier Schritte und kein Exploit:
- 64-KiB-ausgerichtete Regionen finden, die das ext4-Dateisystem des Containers selbst für frei hält.
- Einen einzigen 4-KiB-Block in jede davon schreiben. Das genügt, damit dm-thin einen physischen 64-KiB-Block aus dem gemeinsamen Pool zuweist.
- Das rohe Gerät lesen statt des Dateisystems.
- Die anderen 60 KiB behalten.
Cloudflares eigener Satz für die Primitive ist der ganze Bug: „ein Schreibvorgang über den vollen Block ersetzte dessen vorherigen Inhalt, aber ein kleinerer Schreibvorgang änderte nur den geschriebenen Teil.“
Die geborgenen Blöcke enthielten nutzbare Struktur. Cloudflare berichtet von
„Verzeichnisstrukturen, Datenbankseiten und strukturell vollständigen
SQLite-Datenbanken“ und zählt 2.700 verschiedene fremde Verzeichnis-Inodes
über sechs Produktions-Placements, mit Restmaterial auf 18 von 24 Placements. The
Hacker News berichtet von Daten, die auf 20 von 22 zugrunde liegenden Maschinen auf
vier Kontinenten geborgen wurden. Yomtov listet auf, was er von diesen Blöcken
gelesen hat: „Verzeichnislistings, SQLite-Datenbanken, Chromium-Profile,
.env-Dateien und Zugangsdaten-Dateien.“
Cloudflare nennt zwei Grenzen, die den Vorfall einfassen. Ein Angreifer „konnte kein bestimmtes Opfer auswählen und nicht auf eine aktiv angehängte Platte zugreifen“ — Sie bekamen also, wer auch immer auf dieser Maschine gewesen war, und kein selbst gewähltes Ziel. Und Cloudflare hat aus dem Proof of Concept der Forscher Erkennungssignaturen gebaut, sie gegen die historische Telemetrie der Plattenaktivität laufen lassen und „keinen Hinweis darauf gefunden, dass dieser spezifische Angriffsvektor von jemand anderem ausgenutzt wurde.“
Cloudflare war schnell. Meldung um 15:26 UTC am 4. September; Fehlkonfiguration in der Produktion um 18:45 bestätigt; Runtime-Fix um 21:27 gemergt; Pool-Konfiguration um 22:03 gemergt; Rollout um 23:15 gestartet. Alles davon innerhalb eines Tages. Der Rollout war am 7. September abgeschlossen, die Forscher bestätigten am 14. September, dass ihr Proof of Concept tot war, und Cloudflare räumte am 19. September die letzten Platten-Snapshots aus der Zeit vor der Mitigation weg. Kunden hatten nichts zu tun — und keine Möglichkeit, von innerhalb einer Sandbox zu prüfen, ob ihre eigenen Blöcke sauber angekommen waren.
Jede aktive Grenze hielt
Der Titel von Yomtovs Bericht, „Escaping the Cloudflare Sandbox“, verkauft unter Wert, wie leise dieser Bug ist.
Er fand keinen Speichersicherheitsfehler, keine Privilegieneskalation und keinen Container-Ausbruch. Jede Grenze um einen laufenden Container hielt für die Dauer des Vorfalls wie entworfen. Kunde B konnte den lebenden Container von Kunde A nicht lesen, und Cloudflare weist darauf hin, dass eine Sandbox auch keine aktiv angehängte Platte erreichen konnte.
Das Leck saß in der Übergabe. Cloudflare gab einen Block von einem Mandanten frei und reichte ihn an den nächsten, und was zwischen diesen beiden Kunden stand, war ein Boolean in einer Pool-Konfiguration.
Forscher richten ihre Aufmerksamkeit darauf, was der Code in einer Sandbox jetzt gerade erreichen kann, und viel weniger darauf, was der letzte Bewohner hinterlassen hat. Diese zweite Frage hat meistens eine langweilige Antwort: die Plattform nullt den Block. Die Antwort hält, bis ein Ingenieur das Nullen aus Durchsatzgründen abschaltet.
Accomplish zählt das als seinen sechsten veröffentlichten Sandbox-Ausbruch seit Juli 2026. Die vorherigen fünf: SharedRoot in Claude Cowork, Beltdown in Claude Code, Beltdown2 in Cursors CLI, einer im VMM von Docker und einer in OpenAIs Codex-Sandbox. Fünf dieser sechs führen Code aus, den ein Agent geschrieben hat. Yomtovs eigenes Fazit ist eine Zeile lang: „Isolation kann auf viele Weisen scheitern.“
Genau hierher sollte der Code der Agenten wandern
Cloudflare Sandboxes läuft auf Containers und hat den Bug damit geerbt. Sandboxes ist außerdem das Produkt, das Cloudflare für genau die Sache verkauft, über die dieses Blog immer weiter schreibt. Aus Cloudflares eigener Dokumentation: das SDK existiert, um „nicht vertrauenswürdigen Code sicher in isolierten Umgebungen auszuführen“, es dient dazu, „von großen Sprachmodellen erzeugten Code sicher und zuverlässig auszuführen“, und es passt für „KI-Agenten, Code-Assistenten und autonome Systeme, die nicht vertrauenswürdigen Code ausführen müssen.“ Jede Sandbox läuft „in ihrem eigenen isolierten Container mit einer vollständigen Linux-Umgebung und bietet starke Sicherheitsgrenzen bei gleichbleibender Performance.“
Jeder Teilsatz davon ist etwas, das man vernünftigerweise will, und er beschreibt die Bromure-Workspace-VM etwa so gut, wie er eine Cloudflare Sandbox beschreibt. Der Unterschied ist, wer sonst auf der Maschine ist.
Die Ausführung der Agenten von Ihrem Laptop wegzuschieben verlagert eine Vertrauensentscheidung, es entfernt sie nicht. Sie vertrauen jetzt einem Pool-Allokator, den Sie nicht sehen können, in einem Placement, das Sie nicht gewählt haben, neben Mandanten, die niemand für Sie benennen wird. Das kann der richtige Handel sein. Gehen Sie ihn absichtlich ein, und stellen Sie zuerst die Frage nach dem Rückstand: woher kommen meine freien Blöcke, und was war darin.
Die Platte ist eine Datei auf Ihrem Mac
Bromure Agentic Coding beantwortet diese Frage, indem es keinen Pool hat.
Jeder Workspace bildet auf genau eine VM ab. Zwei Workspaces teilen sich nie eine
VM, und ein Workspace hat nie zwei. Die VM bootet von zwei virtuellen Platten, die
gewöhnliche Dateien im eigenen Verzeichnis dieses Workspace auf Ihrem Mac sind.
disk.img ist die Systemplatte, beim ersten Start als APFS-Copy-on-Write-Klon des
lokalen Ubuntu-Basis-Images erzeugt: sofort da, und kostenlos, bis der Gast
schreibt. home.img ist ein privates, sparse ext4-Image, das /home/ubuntu hält
und als zweites virtio-blk-Gerät angehängt ist.
Die Vier-Schritte-Technik hat hier nichts, worauf sie landen könnte. Ein Agent im Gast kann das rohe Blockgerät statt des Dateisystems lesen, weil er dort drin root ist, und das ist in Ordnung. Er erreicht eine Image-Datei, die zu einem Workspace gehört. Die Blöcke, in die diese Datei hineinwächst, kommen vom APFS-Volume Ihres eigenen Mac, und der vorherige Bewohner eines freien Blocks auf Ihrem Mac waren Sie.
Ein Objekt wird zwischen Workspaces geteilt, und „nichts wird geteilt“ wäre die
falsche Behauptung, also benennen wir es: jede Workspace-Platte wird von base.img
geklont. Ubuntu 24.04, 24 GB logisch und 6 bis 8 GB physisch, gegen einen
signierten Image-Katalog geholt, der eine ed25519-Signatur mit demselben Schlüssel
trägt, der die App-Updates signiert, und der die Identität des Images, seinen
SHA-256 und jeden Postinstall-Befehl abdeckt, mit Rollback-Schutz und Ablehnung
unsignierter Kataloge. Es ist auf jeder Installation byteidentisch und enthält
nichts von Ihnen. Das ist die richtige Art von Sache, die man teilt: ein
öffentliches Artefakt, dessen Aufgabe es ist, überall identisch zu sein.
Und der Rückstand wäre wertlos
Das Blocklayout ist die halbe Antwort. Die andere Hälfte ist, was ein
Coding-Agent auf die Platte schreibt — und genau das machte diesen Bug
meldenswert: .env-Dateien, Zugangsdaten-Dateien, Chromium-Profile.
In einem Bromure-Workspace existieren diese Dateien, und die Werkzeuge, die sie
lesen, funktionieren wie immer, aber die Werte darin sind falsch. Keine Datei,
keine Umgebungsvariable und kein Prozess in der VM hält jemals einen echten
API-Schlüssel, ein echtes OAuth-Token, ein echtes AWS-Secret oder einen echten
privaten SSH-Schlüssel. Der Gast bekommt stattdessen strukturerhaltende
Platzhalter: sk-ant-api03-brm-…, ein GitHub-Token in ghp_-Form, brm_…, pro
Installation deterministisch, damit clientseitige Validierer zufrieden sind und
kein Werkzeug je denkt, ein Schlüssel sei zwischen zwei Sitzungen rotiert worden.
Die echten Werte leben in der In-Memory-Tauschtabelle des Host-Proxys auf dem Mac,
jeder an den Ziel-Host gebunden, zu dem er gehört, und werden auf dem Weg nach
draußen eingesetzt, mit einem Scoping, das exakt-oder-Subdomain ist, niemals
Teilstring. AWS-Anfragen werden host-seitig neu signiert: der Gast signiert mit
einem falschen Secret, der Host entfernt diese Signatur und signiert neu. SSH läuft
signatur-only über eine vsock-Brücke, und die Bytes privater Schlüssel gelangen
überhaupt nie in den Gast.
Das Chromium-Profil behandelt Bromure separat. Das Browser-Panel, das der Agent steuert, läuft in seiner eigenen flüchtigen Alpine-VM, einem Copy-on-Write-Klon im temporären Verzeichnis, das die App löscht, wenn Sie das Panel abbauen. Logins zu behalten ist Opt-in, und dann liegt das Profil auf einer verschlüsselten Platte pro Workspace.
Würde irgendein künftiger Fehler die Blöcke eines Bromure-Gasts offenlegen, käme der Leser mit einem Verzeichnisbaum davon, mit Quellcode, den Sie schon haben, und mit einer Zugangsdaten-Datei, die nirgends ausgegeben werden kann.
Wegwerfbarkeit als Verb
Workspaces sind absichtlich persistent. Programmieren braucht dauerhaften Zustand: geklonte Repos, Paket-Caches, Toolchains, Shell-History. Also kontrolliert Bromure, was die VM halten darf, statt sie jede Nacht zu zerstören, und eine Platte zu löschen ist etwas, um das Sie bitten. Die App ist deutlich bei jeder Art zu bitten:
Auf Basis zurücksetzen
Löscht disk.img, sodass der nächste Start eine frische Kopie des Basis-Images
neu klont. Der Dialog benennt, was geht: alles, was Sie mit apt install
installiert haben, und Ihre Änderungen an /etc, /var, /usr, /opt. Home
überlebt.
Home löschen, Workspace löschen
Home löschen wirft /home/ubuntu und das erzeugte Schlüsselpaar weg. Den
Workspace zu löschen entfernt das ganze Profilverzeichnis, beide Images, die
verschlüsselte Secrets-Datei, jeden Checkpoint und das host-seitige
SSH-Material und gibt dann seine reservierte MAC-Adresse frei.
Wegwerf-VMs und Checkpoints
bromure-cli vm run --rm gibt Ihnen einen Workspace im Docker-Stil, der
gelöscht wird, wenn die VM stoppt. Jeder erfolgreiche Boot lässt einen
Copy-on-Write-Checkpoint von Platte und Home zurück, aufgenommen erst nach
einem Boot, der ein funktionierendes Terminal ergab, also ist jeder davon
erwiesen bootfähig.
Das erzwungene Löschen
Erwischt der Proxy einen Platzhalter als Zugangsdatum auf dem Weg dorthin, wo er nicht hingehört, markiert Bromure den Workspace als kompromittiert, und er bootet nicht wieder, bis Sie seine Platte und sein Home löschen. Ihre Einstellungen, Tokens und SSH-Schlüssel bleiben, und das Löschen berührt nie gemeinsame Host-Ordner.
Dieser Satz von Verben ist der Unterschied zwischen einer Löschung, um die Sie gebeten haben, und einer Löschung, die Sie angenommen haben.
Fragen Sie, was der letzte Mieter hinterlassen hat
Cloudflare hat die Fehlkonfiguration gefunden, sie in neun Stunden behoben, die Pools und die Snapshots geräumt, Erkennungssignaturen gebaut, um die Vergangenheit zu prüfen, und die Blockgröße und den Namen des Flags veröffentlicht. Lesen Sie das als einen Anbieter, der einen schlechten Tag gut handhabt.
„Sandbox“ benennt eine Hoffnung über eine Grenze, und diese Grenze stellte sich als Lebenszyklus einer Ressource heraus statt als Mauer. Die Antwort der Branche auf Agenten, die ungeprüften Code ausführen, war, die Ausführung irgendwo anders hin zu verlegen und darauf zu vertrauen, dass dieses Irgendwo-anders sauber ankommt. Es kommt sauber an, meistens. Prüfen können Sie es von innerhalb der Sandbox nicht, diese Woche nicht und in keiner anderen.
Lassen Sie den Code auf Infrastruktur laufen, die Sie sehen können, und Sie dürfen die Frage nach dem Rückstand selbst beantworten: eine Image-Datei pro Workspace, freie Blöcke von Ihrem eigenen Volume, ein geteiltes Objekt, und das ist ein signiertes öffentliches Basis-Image, und nichts auf dieser Platte, das lesenswert wäre, falls sie doch einmal leckt. Sie zu löschen ist ein Menüpunkt.