Die Sandbox öffnete den Port
CVE-2026-65105 ist ein Netzwerkfehler in NVIDIA NemoClaw, einem Werkzeug, dessen einziger Zweck es ist, einen KI-Agenten in einer Sandbox laufen zu lassen. Die Sandbox ist ein Docker-Container, Container erreichen das Loopback-Interface des Hosts nicht, also startete NemoClaw den lokalen Modellserver stattdessen auf allen Interfaces — womit genau die eine Prüfung abgeschaltet war, die eine Webseite davon abgehalten hätte, mit ihm zu sprechen. Was eine besuchte Seite dann mitnahm, war das Chat-Template des Modells, jene Schicht, die jeden System-Prompt rendert, bevor das Modell ihn liest. In Bromure Agentic Coding lauscht die lokale Engine auf dem Loopback, auf einem Port, den der Gast nie erfährt, und der Gast erreicht sie über vsock statt über ein Netzwerk.
Die Eindämmung selbst hat das Loch geöffnet. Eine Sandbox, die das Loopback-Interface Ihres Rechners nicht erreichen kann, drängt den Modellserver stattdessen auf alle Interfaces — und dann erreicht ihn auch ein Browser-Tab.
Sie betreiben Ihren Coding-Agenten auf die sorgfältige Art. Er lebt in einer Sandbox. Das Modell, mit dem er denkt, läuft auf Ihrem eigenen Rechner, also verlässt kein Prompt das Haus. Sie haben die beiden Dinge getan, die Ihnen alle empfehlen.
Dann öffnen Sie einen Browser-Tab, und von diesem Moment an schreibt Ihr Agent Code mit einem Fehler darin, den zu erwähnen er unterlässt.
Das ist CVE-2026-65105, am 25. August offengelegt von Elad Luz und Ofek Itach bei Oasis Security, deren Analyse das Ganze Drive-by-Agent-Hijacking nennt. Sie gingen vor der Veröffentlichung zum PSIRT von NVIDIA, und die Geschichte lief am selben Tag in The Hacker News, SiliconANGLE und CSO Online. NVIDIA hat ein Advisory und einen Patch.
Das Produkt heißt NemoClaw, NVIDIAs Werkzeug, um einen OpenClaw-Agenten in einer OpenShell-Sandbox mit lokalem Ollama-Backend für die Inferenz auszurollen. Eindämmung ist das Verkaufsargument.
Der Container erreichte das Loopback nicht
Ollama lauscht auf Port 11434 und bindet standardmäßig an 127.0.0.1 — das
Loopback-Interface, erreichbar nur vom Rechner selbst.
OpenShell-Sandboxen sind Docker-Container. Ein Container hat seinen eigenen
Netzwerk-Namespace, also ist 127.0.0.1 im Container der Container und nicht der
Host. Der Agent in der Sandbox kann einen an das Loopback des Hosts gebundenen
Modellserver folglich nicht erreichen.
NemoClaw löste das mit einer Umgebungsvariablen. Es startet Ollama mit
OLLAMA_HOST=0.0.0.0:11434: jedes Interface des Rechners, einschließlich des
einen, das zum Büro-WLAN zeigt. Der Installer druckte weiterhin Using Ollama on localhost:11434, während der Socket der Welt antwortete.
Dann kommt der Schritt, der eine Konfigurationsentscheidung in eine
Verwundbarkeit verwandelt. Ollamas API hat keine Authentifizierung, also trägt
sie stattdessen zwei Wächter. Der erste ist eine CORS-Prüfung des
Origin-Headers. Der zweite ist eine Host-Allowlist, die localhost, den
eigenen Hostnamen des Rechners und Namen mit den Endungen .localhost, .local
oder .internal akzeptiert.
Der zweite Wächter enthält eine Ausnahme. Ollama schaut auf die Adresse, an die
es gebunden ist, und wenn diese Adresse nicht Loopback ist, überspringt es die
Host-Prüfung vollständig. Man sieht, warum das jemand so geschrieben hat: Wer
ein öffentliches Interface bindet, will entfernte Clients, und eine für Loopback
gebaute Host-Allowlist würde jeden einzelnen von ihnen abweisen. Das Ergebnis:
Die Einstellung, die den Port freilegt, ist dieselbe Einstellung, die die
schützende Prüfung entschärft.
Übrig bleibt die CORS-Prüfung, und DNS-Rebinding geht per Konstruktion durch
CORS hindurch. Der Angreifer liefert seine Seite von einer Domain aus, die er
kontrolliert, auf Port 11434, und lässt diese Domain dann erneut auf 127.0.0.1
auflösen. Origin und Host sind nun derselbe vom Angreifer gewählte Hostname,
was Ollama als gleiche Herkunft liest.
Den Rebinding-Mechanismus haben wir letzte Woche im Detail behandelt,
nehmen Sie ihn also als gegeben: Eine Seite, die Sie besuchen, wird zum Client
eines Dienstes auf Ihrem Rechner, und es dauert etwa eine Minute.
Rebinding ist der interessante Weg hinein. Es ist auch der schwerere. Ein Server
auf 0.0.0.0 antwortet jedem anderen Gerät im Netzsegment ganz ohne Browsertrick:
dem Laptop des Gastes, dem Smart-TV, dem kompromittierten Rechner zwei
Schreibtische weiter.
Sie wollten keine Codeausführung
Die API zu erreichen ist die langweilige Hälfte. Was Oasis tat, sobald sie sie hatten, ist der neue Teil.
Der naheliegende Zug wäre, einen bösartigen System-Prompt ins Modell zu
schreiben. Das scheitert hier: OpenClaw schickt bei jeder Anfrage seinen eigenen
System-Prompt im messages-Array mit, und der Prompt des Clients gewinnt gegen
den im Modell gespeicherten. Also gingen die Forscher eine Schicht tiefer.
Ollamas /api/create-Endpunkt akzeptiert ein Feld template. Ein
Chat-Template ist ein Go-Template, das das strukturierte messages-Array —
Rollen, Inhalte, Werkzeugdefinitionen — in den einen flachen Textblock verwandelt,
den das Modell tatsächlich liest. Es läuft zur Inferenzzeit, nachdem der Client
seine Nachrichten übergeben hat, und es fasst sie alle an.
Der Angriff sind drei Anfragen. Das echte Template mit /api/show auslesen.
Dessen Werkzeug-Rendering und Spezialtokens exakt so lassen, wie sie sind, und
nur ändern, wie System-Nachrichten gerendert werden, indem man eine Anweisung
eigener Wahl anhängt. Mit /api/create zurückschreiben.
Der Client schickt weiterhin seinen eigenen sorgfältigen System-Prompt. Das Template hüllt diesen Prompt jedes Mal in den des Angreifers, bevor das Modell ein einziges Token davon sieht. In Elad Luz' Worten, zitiert von CSO Online, sitzt die Anweisung „eine Schicht unterhalb von allem, was ein Guardrail oder ein Betreiber sehen kann“.
Die Änderung landet in der Modelldefinition auf der Platte, sie überlebt also die Konversation, den Reset und den Neustart. Metadaten, Größe und aufgeführte Fähigkeiten des Modells bleiben gleich, und in einer Liste installierter Modelle sieht nichts anders aus. Jeder Konsument dieses Modells bekommt sie: die CLI, an der Sie von Hand herumtippen, und der Agent, der läuft, während Sie beim Essen sind.
Oasis führt auf, wofür eine solche Anweisung taugt. Nichts davon ist dramatisch genug, um aufzufallen.
Den Fehler einbauen
Code produzieren, in dem ein feiner Defekt steckt — die Sorte, die sich im Review gut liest, weil sie geschrieben wurde, um sich im Review gut zu lesen.
Still bleiben
Nie ein Sicherheitsbedenken melden. Ein Agent, der Sie früher vor etwas gewarnt hat und es nicht mehr tut, ist schwer zu bemerken.
Die Wahl lenken
Ein bestimmtes Paket, eine bestimmte URL, eine bestimmte Konfiguration empfehlen. Sie wollten einen Vorschlag; Sie haben einen bekommen.
Alles nach Hause schicken
Wo der Agent Netzwerkzugang hat, Gesprächs- und Dateiinhalte an einen Endpunkt nach Wahl des Angreifers verschicken.
Der Rest der unauthentifizierten API ist Nebenbesetzung: /api/generate und
/api/chat, um Inferenz auf fremder GPU laufen zu lassen, /api/pull, um eine
Platte zu füllen, /api/delete, um die Modelle zu zerstören, /api/push, um
unter dem ollama.com-Konto des Opfers zu veröffentlichen, und /api/me, um
Hostnamen, öffentlichen Schlüssel und angemeldeten Benutzernamen dessen zu
erfahren, bei dem man gerade gelandet ist.
Die Sandbox war nie der Explosionsradius
Oasis ist sorgfältig darin, was die Sandbox geleistet hat und was nicht. Die OpenShell-Sandbox funktioniert: Sie isoliert Dateisystem, Netzwerk und Prozesse, und sie hält den Endpunkt sauber. Ein Agent in einer Organisation verdient sich seinen Platz, indem er Versionskontrolle, CI/CD, interne APIs, Cloud-Konten, Chat und einen Stapel MCP-Server hält. Nehmen Sie den Agenten, und Sie lenken diesen Zugriff. Die Zusammenfassung der Analyse lautet, dass der wahre Explosionsradius den Ressourcen folgt, die der Agent erreichen darf, nicht der Grenze seiner Sandbox.
Das ist die Frage, die ein Container nie für Sie beantwortet, und hier kommt sie mit einer Wendung. Die Eindämmungsschicht hat die Exposition erst geschaffen. Der Docker-Netzwerk-Namespace hat seine Arbeit getan. Ihn zu umgehen setzte den Modellserver ins WLAN.
Wo das lokale Modell in einem Profil wohnt
Bromure Agentic Coding betreibt ebenfalls lokale Inferenz. Die Agenten eines Profils lassen sich statt auf einen Cloud-Anbieter auf ein Modell auf dem Gerät richten, also genau das Feature, das NemoClaw anbietet. Die Installation darunter ist andersherum gebaut, und jeder ihrer Schritte ist eine direkte Antwort auf etwas weiter oben.
Die Engine bindet Loopback, niemals 0.0.0.0. Der Modellserver auf dem Gerät
läuft auf dem Mac, auf 127.0.0.1, auf einem Port, den der Kernel beim Start
vergibt, statt auf einer festen Nummer. Der dynamische Port hat einen langweiligen
Grund: damit Bromure sich nie mit dem streitet, was auf diesem Mac schon die
traditionelle 11434 hält, Ollama und LM Studio eingeschlossen. Er bedeutet auch,
dass es keinen wohlbekannten Port gibt, auf den eine Seite zielen könnte.
Der Gast erreicht sie nicht über ein Netzwerk. In der VM wählt der Agent
127.0.0.1:11434, die Adresse, die er erwartet. Diese Verbindung kommt keiner
Route nahe. Eine Brücke in der VM spleißt den TCP-Strom auf vsock, den
virtio-Socket-Transport, auf Port 8446, und das Host-Ende des Kanals reicht ihn
an die Loopback-Engine weiter. Ein vsock-Kanal ist eine Röhre zwischen einem
Hypervisor und einem Gast. Er hat keine IP-Adresse, keinen Hostnamen und keinen
DNS-Eintrag, es gibt also nichts umzubinden, nichts zu scannen und keinen Weg für
einen Browser, ihn zu wählen. Der Gast erfährt nie, auf welchem Port die Engine
sitzt.
Nichts in Ihrem LAN erreicht die VM. Unter Resources → Network ist der Standardmodus NAT: Ausgehendes funktioniert, und nichts in Ihrem lokalen Netz erreicht die VM. Das schließt jene Hälfte des NemoClaw-Befunds, die gar kein Rebinding braucht — das Gerät im selben WLAN, das den Port direkt wählt — und es schließt sie, ohne dass Sie eine Einstellung ändern.
Es gibt in der VM keine Modelldefinition zum Umschreiben. Gast-Agenten sind
auf eine einzige Modellkennung festgenagelt, bromure-local, und sie adressieren
sie unter bromure.llm, einem synthetischen Hostnamen ohne DNS-Eintrag dahinter.
Der Proxy in der VM fängt diesen Namen ab und leitet ihn an den Host weiter.
Welches Modell antwortet, ist eine Zuordnung, die Sie auf dem Host halten, im
Panel Local Models des Profils, und sie zu ändern ist ein Remapping auf der
Host-Seite: keine Rekonfiguration in der VM, kein Agenten-Neustart. Template,
Gewichte und Routing leben allesamt auf dem Mac. Nichts im Gast hält ein
Äquivalent zu /api/create, weil nichts im Gast das Modell hält.
Lokale Inferenz läuft durch dieselbe Pipeline wie Cloud-Inferenz. Weil dieser Verkehr durch Bromures Proxy geht statt direkt an einen Port, bekommt er dieselbe Behandlung wie ein Aufruf an Anthropic oder OpenAI: denselben Trace, dasselbe Logging und dieselbe Prompt-Injection-Erkennung. Das Panel Prompt Injection bewertet Dateiinhalte, Webseiten und Werkzeugausgaben, die der Agent liest, mit einem lokalen PromptGuard-Modell, und bewertet die Dateien CLAUDE.md, AGENTS.md und GROK.md, die er als Autorität lädt, mit einem feinabgestimmten ModernBERT-Klassifikator plus einem deterministischen Scanner für Payloads aus unsichtbarem Unicode. Funde gehen ins Security Log, oder pausieren die Anfrage, oder liefern ein hartes 451 zurück, je nachdem, welche der drei Reaktionen Sie gewählt haben.
Nehmen Sie jetzt an, das Modell lügt Sie an
Treibt man ein Architekturargument weit genug, sollte jemand es prüfen. Also schenken Sie dem Angreifer den Sieg auf dem Weg, der Ihnen lieber ist: ein vergiftetes Template, ein schlechter Tag bei einem Modellanbieter, eine Prompt-Injection, die durchkam. Ihr Agent arbeitet nun für jemand anderen, und seine Ausgabe liest sich immer noch gut. Führen Sie jene vier Payloads durch ein Profil.
Die Wahl lenken — und die Wahl wird trotzdem geprüft. Dieses Payload stützt
sich am stärksten auf die Autorität des Modells und läuft am härtesten gegen die
Wand. Bromure bewertet jeden Paketabruf am Host-Proxy, bevor der Agent die Antwort
sieht, über npm, PyPI, Cargo, RubyGems, Maven, NuGet, Go Modules und Packagist
hinweg, und der Proxy fragt nicht, wer das Paket vorgeschlagen hat. Eine
Zwei-Tage-Altersschranke ist standardmäßig an, was das meiste abdeckt, was ein
frisch veröffentlichter Typosquat braucht. Schalten Sie die OSV-Abfrage ein,
richten Sie die Paketfilterung auf socket.dev oder Delpi, entfernen Sie
Installationsskripte — und eine Empfehlung muss vier Meinungen überstehen, bei
denen das Modell nichts zu sagen hat. Die .npmrc und pip.conf in der VM können
diese Einstellungen verschärfen. Lockern können sie sie nicht.
Alles nach Hause schicken, über eine Leitung, die Ihnen gehört. Exfiltration
braucht ausgehenden Verkehr. Guardrails → Outbound connections ist eine
Regeltabelle im pf-Stil — eine Aktion, ein Protokoll (tcp, udp, web, any),
ein Host oder CIDR, eine Portliste und für web eine Liste von HTTP-Methoden —
von oben nach unten geprüft, der erste Treffer gewinnt, mit Unmatched traffic
auf Allow oder Deny. Stellen Sie es auf Deny, listen Sie die Hosts, die Ihre
Arbeit braucht, und der Endpunkt des Angreifers ist nicht darunter. Durchgesetzt
wird am virtuellen Switch und auf der SNI-Ebene des Hosts, also ändert nichts, was
der Gast an seinem eigenen Routing tut, das Urteil.
Den Fehler einbauen — und ihn dann ausliefern wollen. Guardrails trägt
außerdem für jeden Dienst, den der Agent erreichen kann, einen Modus:
Block destructive oder Read-only für GitHub, GitLab, Bitbucket, AWS,
Kubernetes, DigitalOcean, Container-Registries und jeden konfigurierten
Datenbank-Endpunkt. Im Nur-Lese-Modus gilt ein git push als Schreibzugriff und
wird blockiert; ein Fetch ist immer erlaubt. Der hintertürige Commit bleibt in der
VM.
Und der Zugang, den er erbt, ist gefälscht. Oasis' Punkt zum Explosionsradius
ist der, in den ein Profil die meiste Mühe steckt. Die Zugangsdaten in der VM sind
Attrappen: brm_…-Platzhalter als Umgebungsvariablen, eine synthetische
~/.kube/config mit Wegwerf-Clientzertifikaten, ein gefälschter Base64-Blob in
~/.docker/config.json und AWS-Anfragen, die auf dem Host neu signiert werden, so
dass alles, was den Proxy umgeht, InvalidSignatureException statt Zugriff
bekommt. Private SSH-Schlüssel
sind überhaupt nie in der VM — der
Host signiert über einen Agenten pro Profil. Schalten Sie Require approval to
use für eine Zugangsdatei ein, und jede Ersetzung wird zu einem Host-Dialog mit
zeitlich begrenzter Freigabe: fünf Minuten, eine Stunde, der Rest der Sitzung.
Ordnerfreigabe ist auf acht von Hand gewählte Verzeichnisse gedeckelt, der Rest
Ihres Macs ist also gar nicht da, um gelesen zu werden.
Und Sie sehen das alles. Das Fenster Security Log (Window → Security Log…) ist eine einzige chronologische Tabelle auf dem Host: Paketurteile, jedes Ziel, das die VM geöffnet hat, samt Erlaubt oder Verweigert, Zugangsdaten-Tausch, Injection-Funde. Gast-Code kann sie nicht bearbeiten, weil Gast-Code sie nicht erreicht. Wenn der Tag endet, bringen Erase home… und Reset to base… unter Resources → Storage das Profil in seinen Zustand direkt nach dem Klonen zurück.
Schalten Sie es ein
Wenn Sie NemoClaw betreiben, nehmen Sie NVIDIAs Patch — er holt Ollama zurück auf
Loopback und setzt einen tokengesicherten Proxy vor alles, was legitim heraus
muss. The Hacker News merkt an, dass der Windows- und WSL-Pfad von diesem Release
nicht vollständig abgedeckt ist, prüfen Sie Ihre Plattform also am Advisory,
statt es anzunehmen. Suchen Sie dann jeden anderen Modellserver auf Ihrem Rechner
und fragen Sie ihn, an welche Adresse er gebunden ist. Die Antwort lautet
häufiger 0.0.0.0, als man erwartet, weil Container immer wieder danach fragen.
In einem Profil sind die Einstellungen, die zwei Minuten wert sind, die übliche kurze Liste. Guardrails → Outbound connections mit Unmatched traffic auf Deny. Credentials → Require approval to use für alles, was Geld ausgeben oder Daten löschen kann. Supply Chain → OSV vulnerability check und socket.dev- oder Delpi-Filterung, falls Sie einen Schlüssel haben, zusätzlich zur ohnehin aktiven Altersschranke. Prompt Injection → beide Detektoren, damit der Verkehr zu Ihrem lokalen Modell so sorgfältig gelesen wird wie der zu einem Cloud-Modell.
Lassen Sie das Modell ruhig weiter auf Ihrem eigenen Rechner laufen. Diese Wahl kauft Ihnen Prompts, die lokal bleiben, und sie ist es wert. Sie sagt nichts darüber, wer sonst mit dem Server sprechen darf, der sie hält — und das ist eine Frage über einen Socket, und ein Socket verdient eine bessere Antwort als eine Umgebungsvariable, die gesetzt wurde, um einen Container zufriedenzustellen. Installieren Sie Bromure Agentic Coding, wählen Sie Ihr Modell auf dem Host und lassen Sie dem Gast eine Röhre statt eines Ports.