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

Die Isolierung führte den Befehl aus

Am 10. August 2026 veröffentlichte Manifold Security eine Schwachstelle in Cursors CLI-Agenten: Die Option, die den Agenten in einem isolierten git worktree startet, las eine JSON-Datei aus dem gerade geklonten Repository und übergab deren Inhalt direkt an eine Shell — vor dem Workspace-Trust-Dialog und außerhalb der Sandbox, selbst wenn man sie eingeschaltet hatte. Kein Modell, keine Prompt Injection, keine Überredung. Bromure Agentic Coding liefert dasselbe worktree-Primitiv, ohne dass ein Repository irgendwo einen Befehl hinterlegen könnte, in einer VM, die es schon vor dem Repository gab.

Sie haben die Option getippt, die „isoliere das“ bedeutet. Genau diese Option hat den Shell-Befehl des Repositorys ausgeführt, als Sie, auf Ihrer Maschine, bevor irgendetwas gefragt hat, ob Sie dem Repository vertrauen.

Am 10. August 2026 veröffentlichte Francisco Rosales von Manifold Security einen Fund in Cursors Kommandozeilen-Coding-Agenten, den The Hacker News drei Tage später in seinem ThreatsDay-Überblick aufgriff. Der Proof of Concept öffnet einen Taschenrechner. Das ist die höfliche Fassung einer Liste, die Manifold ausbuchstabiert: ~/.ssh lesen, Cloud-Zugangsdaten aus der Umgebung nehmen, eine Reverse Shell öffnen, Persistenz schreiben.

Lesen Sie den Bericht wegen der Zustellung, nicht wegen der Nutzlast. Niemand hat etwas injiziert, niemand hat ein Modell überredet, kein raffinierter Satz versteckte sich in einer README. Eine versionierte JSON-Datei in einem Repository nannte einen Befehl, und ausgerechnet der Teil des Agenten, dessen ganze Aufgabe Isolierung ist, führte ihn aus.

Eine Option, eine JSON-Datei und die falsche Reihenfolge

cursor-agent ist die Terminal-Fassung von Cursors Coding-Agenten. Einen Agenten auf den eigenen Arbeitsbaum loszulassen, macht nervös, also bietet die CLI Eindämmung an, dokumentiert in ihrer eigenen Parameterreferenz:

-w, --worktree [name]    Start in an isolated git worktree at
     ~/.cursor/worktrees/<reponame>/<name>

Ein frischer worktree ist ein sauberer Checkout und hat deshalb keine Ihrer Build-Artefakte. Um ihn benutzbar zu machen, führt die CLI beim Anlegen standardmäßig einen Setup-Schritt aus. Dieser Schritt liest .cursor/worktrees.json aus dem gerade ausgecheckten Repository und übergibt den Wert von setup-worktree direkt an sh -c:

{
  "setup-worktree": "<any shell command>"
}

Manifolds Beschreibung dessen, was zwischen diesem Wert und der Shell stand, ist drei Wörter lang: „Kein Parsing, keine Allowlist, kein Dialog.“

.cursor/worktrees.json ist eine gewöhnliche versionierte Datei. Sie kommt mit einem schlichten git clone mit, wie eine README oder eine Lockdatei. In Builds vor 2026.07.23-e383d2b liefen Worktree-Anlage und Setup während der Workspace-Auflösung — und die Workspace-Auflösung war fertig, bevor der Codepfad mit dem Workspace-Trust-Dialog überhaupt an die Reihe kam. Der Befehl lief also zuerst. In der Aufzeichnung, die Manifolds Bericht beiliegt, druckt das Terminal noch Running worktree setup commands…, der Taschenrechner geht auf, und erst danach erscheint die Frage, ob Sie diesem Verzeichnis vertrauen.

Cursor sagt deutlich, wozu dieser Dialog da ist: Nichts, was das Repository kontrolliert, soll laufen, bevor Sie ihn bestätigen. Wenn doch etwas läuft, hat die Branche einen Namen für diese Fehlerklasse — Pre-Trust-Ausführung — und Cursor hat dafür schon einmal einen Fix ausgeliefert, im selben Verzeichnis. 2025 startete eine vom Repository mitgelieferte .cursor/mcp.json den darin konfigurierten Server automatisch, sobald man das Projekt öffnete. Daraus wurde CVE-2025-64109, eingestuft als High mit CVSS 8.8. Eine zu freizügige Behandlung von .cursor/cli.json in derselben CLI wurde zu CVE-2025-61592, ebenfalls High, ebenfalls 8.8. Den -w-Worktree-Pfad gab es damals noch nicht. Er kam fünf Monate nach jenem Fix, mit demselben Primitiv und ohne Sperre.

Manifold meldete den Fund am 20. Juli. Cursor lieferte die Umsortierung am 23. Juli aus: Der Trust-Dialog erscheint jetzt zuerst, und der Setup-Befehl wartet, bis dem Workspace vertraut wird. Am 29. Juli schloss Cursor den Bericht als Informative mit der Begründung, die Ausnutzung setze voraus, dass der Nutzer ein vom Angreifer kontrolliertes Repository klont. Manifolds Antwort ist die, die man behalten sollte. Ein Repository zu klonen ist genau das, wofür das Produkt da ist, und es war auch die Voraussetzung von CVE-2025-64109, dem Bug, den Cursor mit 8.8 bewertete und behob. Das Klonen beschreibt die Zustellung. Der Defekt liegt woanders.

Vor 2026.07.23-e383d2b — cursor-agent -w demogit clone.cursor/worktrees.jsonkommt mit, versioniertWorkspace-Auflösungworktree angelegt,Setup liest die Dateish -c "<ihr Befehl>"Ihr Konto, Ihre Umgebung,Sandbox: insecure_noneWorkspaceTrust-Dialog„vertrauen?“Der Dialog erschien, nachdem der Befehl des Repositorys längst gelaufen war.Nach dem Juli-Fix — umsortiertWorkspaceTrust-Dialogjetzt zuerstSie drücken [a] Trustfür ein Repository, dasSie zum Lesen klontensh -c "<ihr Befehl>"weiter Ihr Konto, Ihre Umgebung,weiter insecure_none — --sandbox enabled greift nichtEine andere Reihenfolge derselben drei Dinge, alle entschieden vom Prozess, den sie einschränken sollten.
Drei Kontrollen, alle innerhalb des Prozesses, den sie einschränken sollten. In Builds vor 2026.07.23-e383d2b lief der Worktree-Setup-Befehl während der Workspace-Auflösung — noch vor dem Trust-Dialog — und unter einer Sandbox-Policy, die fest auf insecure_none stand, woran --sandbox enabled nichts ändert. Der Juli-Fix schob den Befehl hinter die Trust-Sperre. Es ist immer noch dieselbe Shell mit derselben Reichweite in dasselbe Benutzerkonto.

Die Einstellung, die Sie aktiviert hatten, erreichte diesen Pfad nicht

Es gibt einen zweiten Strang, und er hat den Fix überlebt.

Der Setup-Schritt läuft unter einer fest verdrahteten Sandbox-Policy namens insecure_none. Das ist Cursors eigener Name für diesen Wert: In sandbox.json akzeptiert type die Werte workspace_readwrite (Standard), workspace_readonly oder insecure_none, was die Sandbox vollständig abschaltet. Der Worktree-Setup-Pfad ist auf den letzten festgenagelt. --sandbox enabled zu übergeben ändert daran nichts. Manifold über aktuelle Builds: Ein Update schließe „das Pre-Trust-Fenster, nicht die Sandbox-Lücke“.

Legt man beide Stränge nebeneinander, bekommt man etwas, das dieses konkrete Produkt überdauert. Die Trust-Sperre war ein Schritt in einer Abfolge, also konnte sie an der falschen Stelle landen. Die Sandbox war eine Einstellung, also konnte ein Codepfad sich davon ausnehmen. Der worktree trug das Wort Isolierung im Namen, also lasen Nutzer Eindämmung hinein. Cursors eigener Code entschied alle drei, zu selbstgewählten Zeitpunkten, innerhalb des Prozesses, den sie einschränken sollten. Das ist dasselbe Versagen, das vor zwei Wochen das Sicherheitsflag einer Bibliothek besiegt hat, und das hinter sieben Sandbox-Ausbrüchen steckt, bei denen nichts aus einer Sandbox ausgebrochen ist.

Isolierung, die sich Ihr Benutzerkonto teilt

-w isoliert den Arbeitsbaum. Es gibt dem Agenten einen eigenen Checkout, damit er Ihre nicht committeten Änderungen nicht zertrampelt — ein echtes Problem und eine echte Lösung. Niemand hat das gebaut, um die Maschine zu isolieren. Der worktree liegt unter ~/.cursor/worktrees/, in Ihrem Konto, mit Ihrer Umgebung, Ihrem ~/.ssh, Ihrem Shell-Profil, Ihren Cloud-Zugangsdaten und Ihrem Schlüsselbund einen Syscall entfernt. Manifolds Liste dessen, was der Setup-Befehl hätte tun können, liest sich wie eine Inventur dieses Home-Verzeichnisses.

Also: Ein Repository, das Sie noch nicht gelesen hatten, wählte einen Befehl, und ausgerechnet die Funktion, die Sie zur Sicherheit aufgerufen hatten, führte ihn aus. Eine JSON-Datei und eine Shell, während das Modell die ganze Sache aussaß.

Der Großteil der Debatte über Agentensicherheit ist zum Modell abgedriftet. Ist es leichtgläubig, lässt es sich überreden, hat es etwas gelesen, was es nicht hätte lesen sollen. Diese Fragen zählen, und wir widmen ihnen viele Beiträge. Unterdessen ist der sicherste Weg, 2026 Code auf dem Laptop eines Entwicklers auszuführen, ihn in eine Datei zu schreiben, die ein Werkzeug beim Start liest, und zu warten, bis jemand klont.

Ein worktree ohne Platz für einen Befehl

Bromure Agentic Coding liefert dasselbe Primitiv, weil das Primitiv gut ist. Drücken Sie ⇧⌘G in einem Repo-Tab, tippen Sie einen Aufgabennamen, wählen Sie einen Agenten — und Bromure schneidet vom aktuellen Commit einen Branch wt/<slug>, checkt ihn unter ~/.bromure/worktrees/<repo>/<slug> aus, öffnet dort einen Tab und startet den Agenten mit Ihrem Prompt. Mehrere Aufgaben, mehrere Branches, mehrere Agenten, ein Repository — das Flottenmuster.

Bromures Setup-Schritt hat dieselbe Aufgabe wie der von Cursor: Einem sauberen Checkout fehlen die gitignorierten Dateien, die ein Agent braucht, also muss etwas sie herüberbringen. Der Unterschied liegt darin, was das Repository dazu sagen darf. Das Repo kann eine .worktreeinclude-Datei mitliefern, und jede Zeile darin, die kein Kommentar ist, ist ein Pfad relativ zur Wurzel des Haupt-Worktrees. Bromure kopiert jeden davon mit cp -a, und nur dann, wenn die Quelle existiert und das Ziel nicht. Kein Feld in dieser Datei enthält einen Befehl, also gibt es kein sh -c, dessen Reihenfolge man richtig treffen müsste, und keine Ordnungsfrage, die man falsch beantworten könnte. Das Schlimmste, worum eine feindselige .worktreeinclude bitten kann, ist, dass eine Datei in den Checkout kopiert wird. Das ist das ganze Vokabular.

Der größere Unterschied ist, wo das alles passiert.

Worktree in Ihrem Benutzerkontosetup-worktree → sh -cvom Repository gewählt, als Sie ausgeführtwas ein Verzeichnis entfernt liegt~/.ssh/id_ed25519AWS_SECRET_ACCESS_KEY, ANTHROPIC_API_KEY~/.git-credentials, ~/.kube/config~/.zshrc — Persistenzausgehend: eine gewöhnliche Verbindungvon einem gewöhnlichen EntwicklerwerkzeugIsolierter Arbeitsbaum, geteilte Maschine.Worktree in einem Bromure-Profil.worktreeinclude → cp -anur Pfade — kein Feld enthält einen BefehlWegwerf-Linux-VM · vor dem Klonen erzeugtkein privater Schlüssel — Host-ssh-agent via vsockEnv-Zugangsdaten sind Köder (brm_…, Fake-kubeconfig)Persistenz verfällt mit der Aufgabeausgehend: am Host-Proxy geprüft —Köder außerhalb seines Scope → Aufruf abgebrochen,451 an den Gast, VM pausiert, roter AlarmBeide Achsen: der worktree isoliert den Baum, der Hypervisor die Maschine.
Dasselbe Repository, derselbe Setup-Schritt, zwei verschiedene Maschinen. Links ist der worktree ein Verzeichnis in Ihrem Konto: Was dort läuft, erreicht Ihre Schlüssel, Ihre Tokens und Ihr Shell-Profil. Rechts liegt der worktree in einer Wegwerf-VM, die es schon gab, bevor das Repository geklont wurde — die privaten Schlüssel sind nie hineingelangt, die erreichbaren Zugangsdaten sind Köder, und die ausgehende Anfrage, die einen davon trägt, wird am Host-Proxy abgebrochen, bevor das Ziel ein einziges Byte sieht.

Führen Sie den Befehl aus. Sehen Sie, was er findet.

Nehmen Sie Manifolds Liste und lassen Sie sie durch ein Profil laufen — und gewähren Sie dem Angreifer alles: vor dem Trust-Dialog, ohne Sandbox, meinetwegen root im Gast.

~/.ssh lesen. Da ist nichts zu lesen. Die privaten Schlüssel eines Profils bleiben auf dem Host. Die VM bekommt ein SSH_AUTH_SOCK, das auf /tmp/bromure-agent.sock zeigt, über vsock gebrückt zu einem profilspezifischen Agenten auf Ihrem Mac — und Bromure lässt Ihren macOS-launchd-Agenten absichtlich unverbunden. Das Agentenprotokoll kennt Anfragen für „liste meine öffentlichen Schlüssel“ und „signiere diese Challenge“. Es kennt keine Anfrage, die „gib den privaten Schlüssel heraus“ bedeutet. Schalten Sie Require approval to use ein, und jede Signatur wird zu einem Dialog auf dem Host mit einer zeitlich begrenzten Freigabe — fünf Minuten, eine Stunde, der Rest der Sitzung.

Cloud-Zugangsdaten aus der Umgebung nehmen. Sie sind da, sie sehen richtig aus, und sie sind Fälschungen. Alles im Credentials-Panel eines Profils wird als Platzhalter injiziert und vom Host-Proxy auf der Leitung gegen den echten Wert getauscht: brm_… für generische API-Schlüssel, eine synthetische ~/.kube/config mit Wegwerf-Client-Zertifikaten, ein gefälschter Base64-Blob in ~/.docker/config.json, ~/.git-credentials, AWS-Material, das hostseitig neu signiert wird und jedem, der den Proxy umgehen will, mit InvalidSignatureException antwortet. Der Diebstahl gelingt und bringt nichts Brauchbares ein.

Eine Reverse Shell öffnen. Jetzt muss der Angreifer etwas über eine Leitung schaffen, und die Leitung gehört dem Host. Jede ausgehende Anfrage der VM wird mit einem Aho-Corasick-Automaten gegen die für das Profil geprägten Köder geprüft — Header und Body, die ganze Anfrage, nicht nur die Teile, die nach Zugangsdaten aussehen. Ein Köder auf dem Weg zu einem Host außerhalb des Scopes, für den er geprägt wurde, ist die Signatur einer Maschine, die etwas exfiltriert, das sie nicht einmal kennen dürfte. Der Proxy bricht den Upstream-Aufruf ab, bevor das Ziel ein einziges Byte sieht, gibt dem Gast ein 451 zurück, pausiert die VM, färbt das eingefrorene Bild rot und löst einen Alarm aus, der die Zugangsdaten nennt, den Host, für den sie geprägt wurden, und den Host, zu dem sie stattdessen gingen. Sie entscheiden: herunterfahren, zur Untersuchung sichern — Festplattenabbild, Home-Verzeichnis, geteilte Ordner, gebündelt und so markiert, dass das Profil ohne Wipe nicht mehr bootet — oder weitermachen.

Persistenz schreiben. Die Lebensdauer der Maschine ist eine Aufgabe. Erase home setzt /home/ubuntu zurück, und Reset to base klont die Workspace-Systemplatte neu.

Unterdessen geht die Arbeit weiter, die Sie eigentlich wollten. Der Agent durchsieht das Repo, lässt die Tests laufen, öffnet den Pull Request. Der Befehl des Repositorys ist gelaufen — in einem Raum, in dem Laufen alles war, was er tun durfte.

Der Teil, den Patchen nicht abdeckt

Noch ein Detail aus Manifolds Bericht, und es hat die längste Haltbarkeit. Cursor veröffentlichte für den Worktree-Pfad kein Advisory und ließ ihn aus dem Juli-Changelog heraus, der Fix kam also in einem Routine-Build. Wer auf einer betroffenen Version war, hatte keine Möglichkeit zu erfahren, dass ein Update einen Pfad für Pre-Trust-Ausführung schließt. Sie haben heute keine Möglichkeit zu erfahren, welches Werkzeug auf Ihrem Laptop noch einen offen hat, denn dieser Pfad ist immer irgendeine Datei, die ein Werkzeug beim Start liest und die niemand geprüft hat.

Cursor hat diesen hier in drei Tagen geschlossen, das ist schnell. Cursor hat 2025 auch die mcp.json-Variante geschlossen, und fünf Monate später kam ein neues Feature mit demselben Primitiv. So sieht es aus, wenn man Features in eine Startsequenz hineinbaut: Jede Fähigkeit fügt einen Schritt hinzu, und jeder Schritt ist eine Sache mehr, die man an einem Donnerstag richtig einsortieren muss.

Ein Hypervisor ist kein Schritt in dieser Abfolge. Er liest weder .cursor/worktrees.json noch .worktreeinclude noch sonst irgendetwas in Ihrem Repository. Er war vor dem Klonen da, er hat kein Policy-Feld, das ein Codepfad auf insecure_none festnageln könnte, und seine Zusage — diese Maschine ist zum Wegwerfen, diese Zugangsdaten sind falsch, diese Leitung wird beobachtet — ist an dem Tag, an dem ein Bypass veröffentlicht wird, dieselbe wie an dem Tag, an dem er gepatcht wird.

Klonen Sie weiter Repositories, die Sie nicht gelesen haben. Unbekannten Code zu prüfen ist die Arbeit, und sie einem Agenten zu übergeben ist der Sinn davon, einen zu haben. Hören Sie nur auf, diese Prüfung im selben Konto wie Ihre SSH-Schlüssel stattfinden zu lassen. Installieren Sie Bromure Agentic Coding, geben Sie jeder Aufgabe ihren eigenen Branch, ihren eigenen Checkout und ihre eigene Wegwerfmaschine — und wenn sich das nächste Mal herausstellt, dass ein Startpfad ausführt, was immer eine JSON-Datei sagt (und das wird passieren), läuft er in einem Raum, der dafür gebaut wurde.