isolated-vm, falla critica può trasformare un sandbox JavaScript in RCE sull’host
Schwachstellen

Illustration mit KI erzeugt

isolated-vm: Kritische Schwachstelle kann eine JavaScript-Sandbox in eine RCE auf dem Host verwandeln

Isolated-vm Schwachstelle erlaubt RCE über JavaScript-Sandbox durch Type Confusion und TOCTOU. Embedder mit nicht vertrauenswürdigem Code gefährdet.

Von künstlicher Intelligenz erzeugter Text, ohne menschliche Überprüfung veröffentlicht. KI-Transparenz

Speicherfehler durchbricht die Grenze zwischen Guest und Host

Eine kritische Schwachstelle in der Node.js-Bibliothek isolated-vm ermöglicht es nicht vertrauenswürdigem JavaScript-Code, Abstürze des Hostprozesses auszulösen und unter günstigen Bedingungen die Kontrolle über dessen Ausführungsfluss zu übernehmen.

Betroffen ist nativer C++-Code, der JavaScript-Objekte von V8 mit den von isolated-vm verwendeten Speicherstrukturen verbindet. Die Schwachstelle kombiniert Type Confusion, Speicherkorruption und eine Time-of-Check/Time-of-Use-Bedingung (TOCTOU).

Die Auswirkungen sind besonders gravierend, da isolated-vm gerade dafür eingesetzt wird, potenziell schädlichen Code innerhalb von V8-Isolates auszuführen. Diese Umgebungen trennen Heap, Ausführungsstatus und Garbage Collector und bieten damit eine Sicherheitsgrenze, ohne zwingend Container oder virtuelle Maschinen zu erfordern.

Der Fehler kompromittiert diese Grenze. Guest-Code kann den Hostprozess beeinflussen und potenziell eine Remote-Codeausführung auf dem Host ermöglichen. Es liegen keine Hinweise auf eine Ausnutzung der Schwachstelle in realen Kampagnen vor.

Die Schwachstelle wurde am 21. August 2026 entdeckt. Eine zugehörige CVE-Nummer ist nicht bekannt.

Der Fehler entsteht durch das zweimalige Auslesen von transferList

Der Einstiegspunkt ist der Mechanismus:

ivm.ExternalCopy(value, { transferList })

ExternalCopy ermöglicht es, Daten in einem Isolate zu serialisieren und in einem anderen wiederherzustellen. Um große ArrayBuffer effizient zu übertragen, kann der Quellpuffer „detached“ und der zugehörige Speicherbereich an das Ziel übergeben werden.

Beim Erstellen von ExternalCopySerialized analysiert isolated-vm transferList jedoch zweimal. Beim ersten Durchlauf wird geprüft, ob jedes Element ein ArrayBuffer ist. Beim zweiten Durchlauf werden die Elemente erneut abgerufen und konvertiert, ohne die Typprüfung zu wiederholen.

Dieser Unterschied ist entscheidend. Das Auslesen der Elemente erfolgt über Get(), das nicht nur einen bereits vorhandenen Wert abruft, sondern auch JavaScript-Accessors ausführen kann, darunter Index-Getter.

Ein vom Guest kontrollierter Getter kann daher während der Validierung einen echten ArrayBuffer zurückgeben und beim zweiten Auslesen einen völlig anderen Wert liefern. Dieser neue Wert wird anschließend an As<ArrayBuffer>() übergeben. In diesem Pfad fungiert die Methode als ungeprüfter Cast und nicht als sichere Konvertierung.

Damit bezieht sich die Prüfung auf einen Wert, während die anschließende Verwendung einen anderen betreffen kann.

Wie der geprüfte Wert den C++-Code erreicht

Die verwundbare Kette durchläuft mehrere interne Komponenten:

  • src/external_copy/serializer.cc, wo transferList zweimal iteriert wird;
  • src/isolate/generic/array.h:42, dessen Iterator die Elemente über array->Get(context, index) ausliest;
  • src/external_copy/external_copy.cc:397, wo ExternalCopyArrayBuffer::Transfer den Handle fälschlicherweise als ArrayBuffer verwendet.

Beim zweiten Durchlauf kann der Handle somit einen Wert enthalten, der keinen Puffer repräsentiert. Der Code führt dennoch Operationen aus, die einem gültigen Objekt vorbehalten sind, darunter:

  • prüfen, ob der Puffer detached werden kann;
  • den zugehörigen Backing Store abrufen;
  • den Puffer detach-en;
  • den mit dem Speicher verbundenen shared_ptr<BackingStore> verwalten.

Eine kleine Ganzzahl wie 0x41414141 kann von V8 als SMI interpretiert werden, also als direkt im getaggten Wert dargestellte Ganzzahl. Der native Code behandelt sie jedoch wie ein Objekt und versucht, sie zu dereferenzieren.

Das Ergebnis ist eine aus vom Angreifer kontrollierten Daten berechnete Adresse. Bei der Zerstörung des shared_ptr kann der Pfad zudem einen indirekten Aufruf über einen aus diesem Speicher gelesenen Vtable-Zeiger ausführen. Dadurch entsteht eine mögliche Primitive für Control-Flow Hijacking, also die Umleitung des Ausführungsflusses des Prozesses.

Die technische Klassifizierung umfasst CWE-843, Zugriff auf eine Ressource über einen inkompatiblen Typ, sowie CWE-704, fehlerhafte Typinterpretation oder -konvertierung.

Der Guest kann die API auch indirekt erreichen

Der Konstruktor ExternalCopy wird auf der Host-Seite bereitgestellt. Ein Angriff setzt jedoch nicht zwingend voraus, dass der Host die API direkt mit bereits manipulierten Daten aufruft.

Die Klasse kann über die Option externalCopy des transferable-Mechanismus an den Guest übertragen werden. Es genügt, wenn dem nicht vertrauenswürdigen Code auch nur eine einzige ivm.Reference zur Verfügung steht. Über diese Referenz kann er den Konstruktor folgendermaßen abrufen:

const ExternalCopy =
  ref.getSync('anyKey', { externalCopy: true }).constructor;

Anschließend kann der Guest eine transferList mit einem Getter vorbereiten, dessen Verhalten sich ändert. Beim ersten Auslesen gibt der Getter einen gültigen ArrayBuffer zurück und besteht damit die anfängliche Prüfung. Beim zweiten kann er beispielsweise 0x41414141 liefern.

Betroffen sind somit Embedder, die nicht vertrauenswürdiges JavaScript in einem Isolate ausführen und diesem Code mindestens ein ivm.Reference-Objekt zur Verfügung stellen.

Es gibt auch ein direkteres Szenario: Host-Code kann verwundbar sein, wenn er ein vom Benutzer kontrollierbares Array transferList an ExternalCopy übergibt. In diesem Fall muss der Guest keine übertragene Referenz besitzen.

Der PoC demonstriert einen kontrollierbaren Absturz

Der Proof of Concept wurde mit folgenden Komponenten verifiziert:

  • isolated-vm 7.0.0 aus npm;
  • Node.js 26.5.0;
  • macOS auf der Architektur arm64.

Das Problem ist auf jeder Plattform reproduzierbar, auch wenn sich Adressen und Details des Fehlers unterscheiden können.

Die Ausführung des PoC mit:

node poc.js

beendet den Hostprozess mit:

  • Signal SIGSEGV;
  • Exit-Code 139;
  • einem Fehler in v8::ArrayBuffer::IsDetachable;
  • der Fault-Adresse 0x4141414100000047.

Dieser Wert ist aussagekräftig, da er aus der vom Guest kontrollierten Ganzzahl abgeleitet und als SMI interpretiert wird. Es handelt sich daher nicht lediglich um eine Nullzeiger-Dereferenzierung oder einen zufälligen Absturz.

Der Absturz stellt die minimal nachgewiesene Auswirkung dar. Dieselbe Korruption kann in komplexeren Szenarien Lese- oder Schreibzugriffe auf vom Angreifer gewählte Adressen und die Kontrolle über den Ausführungsfluss des Hostprozesses ermöglichen. Daraus ergibt sich das Risiko eines Sandbox-Escape und einer Codeausführung auf dem Host.

Fehlerbereinigte Versionen und Maßnahmen für Administratoren

Korrekturen sind in folgenden Versionen verfügbar:

  • isolated-vm 6.2.0;
  • isolated-vm 7.0.1.

Nutzer des 6er-Zweigs sollten mindestens auf 6.2.0 aktualisieren; Nutzer des 7er-Zweigs mindestens auf 7.0.1. Auch transitive Abhängigkeiten, die isolated-vm einbinden, sollten überprüft werden, insbesondere in Diensten, die von Benutzern bereitgestellte Skripte, Plugins oder Remote-Inhalte ausführen.

Die Korrektur verhindert die Ausführung von JavaScript während des Kopiervorgangs. Dadurch kann sich der Inhalt von transferList zwischen der Validierungsphase und dem Cast nicht ändern.

Priorisierte Maßnahmen sind:

  1. isolated-vm auf die korrigierte Version des verwendeten Zweigs aktualisieren;
  2. Embedder erfassen, die nicht vertrauenswürdiges JavaScript ausführen;
  3. Fälle identifizieren, in denen der Guest ivm.Reference-Objekte erhält;
  4. Verwendungen von ExternalCopy mit durch Eingaben beeinflussbarer transferList überprüfen;
  5. die gemeinsame Nutzung von ivm.Reference mit nicht vertrauenswürdigem Code nach Möglichkeit reduzieren.

Bei der Überwachung sollten Abstürze mit SIGSEGV, Exit-Code 139 sowie ungewöhnlichen oder auf kontrollierte Werte zurückführbaren Fault-Adressen umgehend untersucht werden. Diese Merkmale sind technisch mit dem PoC vereinbar, belegen allein jedoch keine Kompromittierung.

Netzwerk-, datei- oder prozessbasierte Indicators of Compromise sind nicht bekannt. Ebenso ist nicht bekannt, ob die Schwachstelle in den KEV-Katalog der CISA aufgenommen wurde; Informationen zu einer damit verbundenen Frist für die Behebung liegen ebenfalls nicht vor.

Auch interessant

Quellen

Dieser Artikel ist eine eigenständige Aufbereitung auf Basis der folgenden Quellen.

Verwandte Themenisolated-vmSchwachstelleJavaScript-SandboxRemote-CodeausführungType ConfusionTOCTOUNode.jsEmbedder
Zurück zur Startseite