Die Funktion ExternalCopy serialisiert Daten in einem Isolate und rekonstruiert sie in einem anderen. Aus Performancegründen kommt dabei eine transferList zum Einsatz: Große ArrayBuffers werden dort aufgeführt, der zugrunde liegende Speicher wird übertragen, indem der Puffer von der Quelle abgetrennt und dem Ziel übergeben wird.
Der Kern des Problems liegt darin, dass der Rekonstruktor beim Transfer die Liste der Byte-Arrays zweimal durchläuft – und der zweite Durchlauf den Ergebnissen des ersten vertraut. Ist ein Element der transferList als Getter definiert, liefert die Iteration über das JavaScript-Array in beiden Durchläufen nicht zwangsläufig denselben Wert. Diese Time-of-Check/Time-of-Use-Schwäche lässt sich ausnutzen, um einen vom Angreifer kontrollierten Zeiger zu dereferenzieren.
Zwar ist der ExternalCopy-Konstruktor nur vom Host aus erreichbar. Laut EndorLabs kann ein Gast jedoch ivm.Reference ins Visier nehmen – jenen Mechanismus, über den der Host der Sandbox überhaupt etwas zugänglich macht –, um die manipulierte transferList zu konstruieren und die Schwachstelle auszulösen.
Entsprechend weit ist der Kreis der Betroffenen. Im Advisory zu isolated-vm heißt es: „Jeder Einbettende, der nicht vertrauenswürdigen Code in einem Isolate ausführt und auch nur eine einzige Reference dorthin teilt, ist betroffen. Hostcode, der ein vom Aufrufer beeinflusstes Array als transferList übergibt, ist unmittelbar betroffen, ganz ohne Gast.“
Die Korrektur ist in den isolated-vm-Versionen 6.2.0 und 7.0.1 enthalten. Sie verhindert, dass während des Kopiervorgangs überhaupt noch nutzergesteuertes JavaScript ausgeführt wird – damit entfällt die Grundlage für den TOCTOU-Trick.
EndorLabs verortet die Ursache in der nativen Verbindungsschicht: „Die Schwachstelle steckte im nativen Glue-Code – der C++-Anbindung, die Werte über die Grenze hinweg serialisiert. Diese Schicht ist in einer speicherunsicheren Sprache geschrieben, sie manipuliert rohe V8-Handles und Zeiger auf Backing Stores und liest mitten in einer sicherheitskritischen Operation vom Angreifer kontrollierte JavaScript-Objekte erneut ein. Eine einzige ungeprüfte Typumwandlung auf einem erneut gelesenen Wert genügte, um aus einem korrekten Isolationsprimitiv einen vollständigen Ausbruch zu machen.“
Damit richtet sich das Risiko vor allem an Betreiber von Diensten, die fremden JavaScript-Code in V8-Isolates ausführen und dabei auf isolated-vm statt auf Container oder virtuelle Maschinen setzen. Die Sandbox, die genau diese Trennung garantieren soll, lässt sich über den beschriebenen Weg verlassen.
