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

Der Ausschalter lag in der Sandbox

CVE-2026-82533, veröffentlicht am 8. September, ist eine 9,4 in DeepSeek Harness: Der eingesperrte Coding-Agent konnte seine eigene Sandbox mit einem einzigen Shell-Befehl abschalten. Das Harness führte die Befehle des Agents in einer Betriebssystem-Sandbox aus, die Schreibzugriffe auf Dateien einschränkte, und legte seine Steuerebene als HTTP-Oberfläche auf Loopback offen, die die Sandbox nie abdeckte. Die Prüfung, die diese Oberfläche bewachte, las den vom Aufrufer gelieferten Host-Header und sah nie nach, woher die Verbindung kam. In Bromure Agentic Coding ist der Agent innerhalb der VM ohnehin unbeschränkt, und die Steuerebene, die er anrufen müsste, existiert auf seiner Seite der Linie gar nicht.

Dieser hier brauchte keinen Exploit. Der eingesperrte Agent setzte einen Shell-Befehl gegen einen lokalen Port ab, bat die Sandbox, die ihn hielt, sich selbst abzuschalten, und die Sandbox stimmte zu.

DeepSeek Harness führt die Befehle eines Coding-Agents in einer Betriebssystem-Sandbox aus. Die Sandbox ist eng und bewusst gewählt: Schreibzugriffe auf Dateien bleiben im Workspace und in den temporären Ordnern, und alles andere, was der Agent tut, ist das Problem von jemand anderem. Die Kommandozeilen-Referenz des Projekts sagt genau das. In den Standardeinstellungen sind „Lesezugriffe und Netzwerkzugriff nicht eingeschränkt“.

Das Harness hat außerdem eine Weboberfläche. Sie läuft auf derselben Maschine, auf einem lokalen HTTP-Port, und das Harness reicht ihre Adresse an die Shell des Agents weiter, damit Werkzeuge mit ihr sprechen können. Diese Oberfläche ist die Steuerebene: Sie hält den Modus einer Sitzung, einschließlich des Modus namens danger-full-access, der die Sandbox abschaltet und die Freigabeabfragen beendet.

Beide Entwürfe sind gewöhnlich. Stellt man sie nebeneinander, kann der Agent seine eigene Sandbox mit einem Befehl abschalten, weil die Sandbox Loopback nie abdeckte und die Steuerebene nie prüfte, wer da anrief.

Forscher von OX haben es gefunden. VulnCheck hat es am 8. September als CVE-2026-82533 veröffentlicht, CVSS 9,4. Es funktionierte auf einer Standardinstallation, ohne Netzwerkexposition und ohne Zugangsdaten, bis DeepSeek am 27. August einen Fix auslieferte.

Die Prüfung, die den Umschlag las

Die Oberfläche hatte überhaupt keine Authentifizierung. An deren Stelle stand eine Funktion namens isTrustedApiRequest, und DevOps.com zitiert, was sie tat: Sie „las den Host-Request-Header und erlaubte den Zugriff, wenn der Wert eine Loopback-Autorität war oder in einer konfigurierten trustedHosts-Liste auftauchte“.

Der Host-Header ist eine Textzeile, die der Client schreibt. Er sagt, mit welcher Adresse der Client zu sprechen glaubt, und ein Aufrufer irgendwo im Netz kann dort localhost hineintippen. Der wirkliche Ursprung der Verbindung liegt eine Schicht tiefer, in der TCP-Peer-Adresse, und DeepSeeks Prüfung hat diesen Wert nie gelesen. Der CVE-Eintrag legt den Fehler unter CWE-345 ab, Reliance on Untrusted Inputs in a Security Decision.

Der Agent, der in einer Sandbox saß, die Netzwerkaufrufe erlaubte, machte einen an die Oberfläche und setzte seine eigene Sitzung auf danger-full-access mit Freigabe auf never. Wie The Hacker News es formuliert, erforderte der Moduswechsel „keine ausdrückliche Freigabe, weil er Sitzungseinstellungen änderte, statt neue Berechtigungen anzufordern“.

Das Freigabesystem funktionierte wie entworfen. Der Agent bat nie darum, etwas Gefährliches zu tun; er bat darum, eine Einstellung zu ändern, und diese Einstellung regelte, ob nach gefährlichen Dingen überhaupt gefragt wird. Ein Berechtigungstor prüft die Operation, die vor ihm liegt. Diese Anfrage war ein Konfigurationsschreibvorgang, und Konfigurationsschreibvorgänge standen nicht auf seiner Liste.

eine Maschine, ein Prozess, zwei Entscheidungen, die sich nie trafenOS-Sandbox: was sie einschränktdie Shell-Befehle des Coding-AgentsSchreiben → Workspace + Tempvom Betriebssystem erzwungen, und es hieltaußerhalb des Rahmens, so gewolltLesen: unbeschränktNetz: unbeschränkt, Loopback inklusivePOST http://127.0.0.1:…Host: localhostSteuerebene: lokales HTTP, ohne AuthisTrustedApiRequest(req)• liest den Host-Header des Aufrufers• Loopback-Autorität oder trustedHosts → ok• liest nie die TCP-Peer-Adresseder resultierende Sitzungszustandmode = danger-full-accessapproval = neverein Einstellungs-Schreiben, also fragt nichts
Der Ausbruch, vollständig. Die Betriebssystem-Sandbox beschränkt Schreibzugriffe auf Dateien auf den Workspace und die temporären Ordner; Lesezugriffe und Netzwerkaufrufe, Loopback eingeschlossen, liegen von Entwurf her außerhalb ihres Rahmens. Die Steuerebene des Harness lauscht auf einem lokalen HTTP-Port, dessen Adresse die Shell des Agents bereits kennt. Ihre Vertrauensprüfung liest den Host-Header des Aufrufers selbst und sieht nie die TCP-Peer-Adresse an, so dass eine Anfrage aus dem Sandbox-Prozess genauso aussieht wie eine des Entwicklers. Der Agent schreibt dann seinen Sitzungsmodus auf danger-full-access und seine Freigabe-Einstellung auf never. Das ist ein Einstellungs-Schreibvorgang und keine Berechtigungsanfrage, also fragt nichts nach.

Dieselbe Tür, andersherum

Eine Oberfläche, die einem vom Aufrufer gelieferten Header vertraut, kümmert sich nicht darum, aus welcher Richtung die Verbindung ankommt. War der Port über ein Netz erreichbar, funktionierte derselbe Aufruf von außerhalb der Maschine: Ein nicht authentifizierter Fremder konnte die Kontrolle über den Agent übernehmen und jede gespeicherte Unterhaltung exportieren, ohne API-Schlüssel und ohne ein einziges Token für einen Modellaufruf auszugeben. Deshalb beginnt der CVSS-4.0-Vektor mit AV:N, und deshalb ist die Zahl 9,4 statt etwas Lokalem und Mildem.

Die Zeitleiste hat ein Detail, das man behalten sollte. Zwei Entwickler haben den Fund am 13. und 14. August von sich aus im GitHub-Diskussionsforum von DeepSeek gepostet, bevor OX ihn am 24. August bestätigte und bevor eine CVE existierte. Das Repository hatte am 9. September mehr als 216.000 Sterne und keine Sicherheitsrichtlinien-Datei, die beschreibt, wie man eine Schwachstelle privat meldet, also blieb als einziger Ort dafür ein öffentlicher Thread. Der Fix, als er kam, war Authentifizierung: Das Werkzeug druckt nun ein Einmal-Token in seiner Startadresse, der Browser tauscht dieses Token gegen ein signiertes Cookie, und jeder Aufruf der Oberfläche verlangt das Cookie.

Wenn Sie dieses Harness betreiben, prüfen Sie die Version auf Ihrer Maschine statt der Version, die das Projekt ausliefert. Fremde Desktop-Hüllen bringen ihre eigene Kopie mit. 0.1.2-alpha.1 gab es am 27. August nur auf GitHub, 0.1.2-alpha.2 am 30. August war die erste npm-Veröffentlichung mit dem Fix, und eine Windows-Hülle blieb auf 0.1.1-rc.2, bis sie am 6. September auf einen gepatchten Build wechselte.

Ihr Harness hat auch so eine

Sie könnten das als den Fehler eines einzelnen Projekts ablegen und weitergehen. Die Form wandert, denn Agenten-Harnesses treiben lokale Steuerebenen aus: ein Status-Server für das Dashboard, eine IDE-Brücke, ein MCP-Endpunkt, eine Seite auf localhost, die den Diff rendert. Jede davon ist ein kleiner HTTP-Dienst auf Ihrer Maschine, und der Code, den Ihr Agent ausführt, erreicht sie alle, weil der Agent auf dieser Maschine läuft und localhost genau das ist, was „diese Maschine“ heißt.

Sobald eine Steuerebene neben dem sitzt, was sie steuert, entscheidet eine einzige Frage über den Ausgang: Kann die eingesperrte Partei die Einstellungen ihrer Einsperrung adressieren? DeepSeek antwortete mit Ja, über eine Prüfung, die dem Aufrufer aufs Wort glaubte. Eine stärkere Prüfung beantwortet immer noch eine Frage, die nie stellbar hätte sein dürfen. Eine Authentifizierungsfunktion ist Code, Code hat Fallback-Zweige, und dieses Jahr war eine lange Parade von Sicherheitsentscheidungen, die in dem Zweig scheitern, den niemand durchlaufen hat.

Wo der Schalter in einem Bromure-Workspace liegt

Bromure Agentic Coding fängt am anderen Ende an. Ein Bromure-Workspace lässt den Agent unbeschränkt.

Innerhalb des Gasts hat der Agent bereits das, was DeepSeek Harness danger-full-access nennen würde. Das ist der Ruhezustand, so entworfen. Das Handbuch sagt genau das: Ein per Prompt-Injection gekaperter oder sich sonst schlecht benehmender Agent „kann innerhalb des Gasts tun, was er will, aber er kann keinen echten API-Schlüssel lesen, mit keinem echten AWS-Secret signieren und keinen privaten SSH-Schlüssel herausziehen — nichts davon existiert auf seiner Seite der Linie“. Der Agent darf überall im Dateisystem schreiben, ausführen, was er will, und jeden beliebigen Port belegen, also bleibt ihm kein Modus mehr, in den er eskalieren könnte. Die Grenze ist eine Hypervisor-Kante, mit dem Agent auf der anderen Seite.

Der Gast hat deshalb überhaupt keine Adresse für die Steuerebene. Die Policy des Workspace (Guardrails, Zugangsdaten, Firewall-Regeln, MCP-Server) liegt in einer profile.json unter ~/Library/Application Support/BromureAC/profiles/ auf Ihrem Mac, und Sie ändern sie im Fenster Edit workspace. Der Gast hat keinen Dateipfad zu dieser Datei und keine Netzroute zu dem Prozess, der sie liest.

Die beiden Seiten sprechen über Virtio-Sockets, Punkt-zu-Punkt-Brücken zwischen Host und Gast, die außerhalb des VM-Netzes laufen. Eine Workspace-VM hat acht, jede mit einer Aufgabe: 8443 trägt das HTTPS des Gasts zum Host-Proxy, 8444 ist die ssh-agent-Brücke, 8445 versorgt den AWS-Credential-Helper, 5800 bedient Terminal und Dateipfade, 5010 leitet OAuth-Rückrufe weiter. Jede bedient ein festes Protokoll und keine nimmt einen Host-Header entgegen, also hat ein Aufrufer keine trustedHosts-Liste, in die er sich hineinreden könnte. Auf einem vsock ist Identität Topologie: über welche Brücke die Bytes ankamen. Das lässt sich nicht in eine Anfrage tippen.

das Harness: Sandbox und ihre Einstellungen, eine MaschineAgent in der SandboxSchreibzugriffe beschränktNetz unbeschränktkennt die Adresse der OberflächeLoopback-HTTPHeader, den der Aufrufer schreibtSteuerebeneSitzungsmodusFreigabe-Einstellungeine Anfrage von dem entfernt, was sie regeltein Bromure-Workspace: alles drinnen, die Policy drübenWorkspace-VMder Agent hat hier vollen Zugriffüberall schreiben · alles starten · jeder Portkein Modus zum Eskalierenlokale Steuerebenen, die er startet,lauschen auf dem Loopback dieser VMhier existieren keine echten SecretsHypervisorvsock 8443nur HTTPSkein SteuerpfadmacOS-HostProxy pro Workspace: die Draht-GrenzeGuardrails · Egress-Firewall · falsche Secrets:80 und :443 vom virtuellen Switch umgeleitetnichts, was der Gast abschalten kannwo die Policy gespeichert ist~/Library/Application Support/BromureAC/…Dialoge erscheinen hier, in AppKit
Zwei Platzierungen desselben Schalters. Oben: Die Sandbox des Harness und die Steuerebene, die sie regelt, laufen auf einer Maschine, also erreicht der Agent die Einstellungen über Loopback, und das Einzige zwischen ihnen ist eine Prüfung eines Headers, den der Agent selbst schreibt. Unten: Ein Bromure-Workspace gewährt dem Agent alles innerhalb des Gasts und legt die Policy auf die andere Seite des Hypervisors. Der virtuelle Switch leitet das ausgehende HTTPS des Gasts in den Host-Proxy um, ohne Umgebungsvariable, die sich löschen ließe; Guardrails, Egress-Firewall und Credential-Tausch laufen alle dort; und Freigabedialoge erscheinen auf macOS. Der Gast hat für nichts davon eine Adresse.

Freigaben, die sich nicht auf never stellen lassen

Die zweite Hälfte von danger-full-access schaltete die Abfragen ab, und diese Hälfte verdient ihre eigene Antwort. Ein Agent, der seine eigenen Freigaben zum Schweigen bringt, ist der Teil, der mich wachhalten würde.

In einem Bromure-Workspace leben die Abfragen auf dem Host. Der Proxy wirft sie auf, nachdem die Anfrage die VM bereits verlassen hat, also trägt die Sitzung innerhalb des Gasts keine Einstellung, die eine davon unterdrücken könnte. Vor Benutzung fragen hält die erste Verwendung eines Zugangsdatums in einer Sitzung an und bietet zeitlich begrenzte Genehmigungen an: fünf Minuten, eine Stunde, den Rest der Sitzung oder Nicht erlauben. Eine Schreib-Policy auf Vor dem Schreiben fragen stoppt jede Mutation mit einem Dialog unter der Überschrift Allow write on "<scope>" from workspace "<name>"?, der die wörtliche Operation zeigt, das SQL-Statement selbst oder METHOD /path für einen REST-Aufruf. Einmal erlauben legt gar keine Genehmigung an, also fragt der nächste Schreibvorgang erneut. Genehmigungen leben im Speicher und verschwinden, wenn das Sitzungsfenster schließt.

Die Guardrails-Seite formuliert die Eigenschaft in einem Nebensatz: Eine Schreib-Policy wird „im Proxy durchgesetzt, so dass ein kompromittierter Agent in der VM sie nicht umgehen kann“. Die Egress-Firewall darunter arbeitet genauso, eine geordnete Regeltabelle mit einem Unmatched traffic-Schalter, den Sie auf Deny stellen können, zweimal angewendet: einmal am virtuellen Switch nach Ziel-IP und aus dem DNS mitgelesenem Hostnamen, einmal am Proxy nach TLS-Servername und, für web-Regeln, nach HTTP-Methode. Regeländerungen erreichen laufende Sitzungen ohne Neustart.

Ein unbeaufsichtigter Lauf scheitert auf die sichere Weise. Ein Workspace, der kopflos über SSH oder eine Automatisierung gesteuert wird, bekommt dieselben vier Möglichkeiten als Textabfrage in seinem tmux, und keine Antwort bedeutet Verweigerung. Das schlimmste Ergebnis dort ist ein blockierter Aufruf und eine rote Zeile in der Security Timeline. In dieser CVE setzte der Agent die Freigaben auf never, und die Abfragen verschwanden.

Wenn Sie ein Agenten-Harness auf Ihrem Mac betreiben

Fragen Sie, welche lokalen Oberflächen es hat und wer sie aufrufen darf. Innerhalb eines Bromure-Workspace druckt bromure-cli vm ports <workspace> die aktuell lauschenden Sockets des Gasts aus, mit Port, Protokoll, Adresse und Prozess, und markiert reine Loopback-Bindungen. Die Karte Listening Ports im VM-Dashboard zeigt dasselbe. Diese Bestandsaufnahme ist die Frage, an der diese CVE hing, und ein einziger Befehl beantwortet sie.

Wenn die Oberfläche auch nach außen zeigt

Die entfernte Hälfte von CVE-2026-82533 brauchte einen erreichbaren Port. Workspace-VMs laufen in einem privaten NAT-Netz: Sie sind von Ihrem Mac aus erreichbar, aber sie sind „nicht in Ihrem physischen LAN exponiert, und eingehende Verbindungen von anderswo sind nicht möglich, sofern Sie nicht ausdrücklich einen Dienst veröffentlichen“. Ein nicht authentifizierter Agenten-Steuerport, zu dem ein Café-Netz nicht routen kann, lässt Ihnen einen Patch, den Sie nach eigenem Zeitplan einspielen.

Einsperrung, die man widerrufen kann, ist eine Vorliebe

DeepSeek lieferte eine schwache Prüfung aus und behob sie drei Tage, nachdem OX sie bestätigt hatte. Das Bleibende ist das, was die Prüfung bewachte. Eine Grenze, die von der eigenen Laufzeitumgebung eines Prozesses um diesen Prozess gezogen wird, ist eine Grenze, mit der der Prozess verhandeln kann: Sie hat eine Adresse, eine API und ein Einstellungsobjekt mit einem Feld darin. Irgendwo hinter diesem Feld läuft ein Codepfad, der entscheidet, ob dieser Aufrufer es beschreiben darf, und ein Codepfad dieser Art ist eine schlechte Voreinstellung von der Dekoration entfernt.

Ziehen Sie die Grenze unter den Prozess, und es gibt kein Gegenüber mehr, mit dem sich verhandeln ließe. Der Agent in einem Bromure-Workspace hat root, hat das ganze Dateisystem und darf jeden Dienst starten, den er möchte, auf jedem Port. Seine API-Schlüssel sind Attrappen, seine einzige Route ins Netz ist ein Virtio-Socket zu einem Proxy auf Ihrem Mac, und die Datei mit seinen Berechtigungen liegt an einem Ort, den er nicht lesen kann. Geben Sie dem Agent alles auf seiner Seite der Linie, und Sie müssen die Linie nicht mehr verteidigen.

Coding-Agenten werden weiter lokale Steuerebenen austreiben, denn eine Steuerebene ist die Art, wie man ein Dashboard, eine IDE-Brücke oder einen Diff-Betrachter baut. Jedes Projekt muss dann beantworten, ob der Code, den sein Agent ausführt, auf derselben Seite der Linie liegt wie die Einstellungen, die diesen Agent regeln. Wer das falsch beantwortet, dem hält am Ende nur noch die Authentifizierung, und so kommt eine 9,4 auf einen einzigen Shell-Befehl herunter. Installieren Sie Bromure Agentic Coding und legen Sie den Schalter dorthin, wo Ihr Agent ihn nicht erreicht.