Published · yesterdayBuild2 min read
A double-read in isolated-vm turns customer JavaScript into host code execution
GHSA-864f-rcv7-6rh4 lets guest code hand the C++ bindings one type on the first read and a different one on the second. Fixes are in 7.0.1 and 6.2.0.
Written for builders.See today for builders
What happened
- Advisory GHSA-864f-rcv7-6rh4 describes a type confusion in isolated-vm in which isolated JavaScript exploits a double-read difference in values to corrupt the memory of the host Node.js process and take over its control flow.
- The guest reaches the ExternalCopy constructor, and the getter of transferList returns a normal ArrayBuffer on the first read and another attacker-controlled value on the second read.
- The C++ bindings trust the type check from the first read and treat the value as an ArrayBuffer without re-checking the second read, leading to reading and writing control addresses and hijacking host control flow.
- Preconditions are that the host runs untrusted JavaScript inside isolated-vm and passes at least one ivm.Reference, and that the guest can reach ivm.Reference or an attacker-controlled transferList.
- Affected configurations are described as using isolated-vm version 7.0.0 or lower, or version 6.x below 6.2.0.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
A type check that reads a value twice has not checked anything. The bindings validate what the first read returned and then operate on whatever the second read hands back, which is the part the guest controls [3]. Fixing that means either reading once and holding the result, or re-validating at the point of use; a patch that only tightens the check without collapsing the double read leaves the same shape available anywhere else the bindings ask a JavaScript object a question twice.
The entry condition is worth sitting with. The guest needs untrusted execution inside the isolate plus at least one `ivm.Reference` passed in from the host [4]. That reference is the bridge, and the advisory's own fallback for anyone who cannot upgrade is to stop passing references to untrusted code or to turn the feature off entirely [9]. Read those two together and the sandbox stops looking like a wall with a door in it.
The version guidance does not close cleanly. The affected set is given as 7.0.0 or lower, or 6.x below 6.2.0 [5], while the fixed versions are 7.0.1 and 6.2.0 [6]. Taken literally, "7.0.0 or lower" contains 6.2.0, which the same document lists as the remedy [19]. Anyone pinned on the 6.x line cannot resolve their status from that sentence and has to go to the advisory record itself.
Forensics are thin by design. The basic proof of concept ends in `SIGSEGV` and exit 139 [7], with crash sites near `v8::ArrayBuffer::IsDetachable` [8]. The advanced path does not end in a crash; it ends with guest processing in control of the host process [10]. The write-up also notes that the sequence begins inside guest processing with no network signs, and that any outbound traffic afterwards depends entirely on the payload, with nothing published [11]. So the loud artifact belongs to the attempt that failed, and the quiet one is the case you care about.
On the strength of the evidence: the record reports no observed exploitation in public information, and only proof-of-concept-style `transferList` and getter inputs confirmed internally [12]. It also carries a severity of high [13] while the Endor Labs write-up it points to, dated 20 August 2026, is titled as critical [14], and lists the GHSA identifier with no CVE attached [15]. Investigation guidance names audits of code execution nodes and workers in tools like n8n, worker environment variables, cloud credentials and connection destinations [18]. That is where the value sits, and it always did. What changed is the confidence you can place in the isolate that was drawn between it and the customer's expression field [1].
Claim ledger
Ranked by verification strength, evidence, and original report placement.
- [1]
Advisory GHSA-864f-rcv7-6rh4 describes a type confusion in isolated-vm in which isolated JavaScript exploits a double-read difference in values to corrupt the memory of the host Node.js process and take over its control flow.
- [2]
The guest reaches the ExternalCopy constructor, and the getter of transferList returns a normal ArrayBuffer on the first read and another attacker-controlled value on the second read.
ReportedView cited source - [3]
The C++ bindings trust the type check from the first read and treat the value as an ArrayBuffer without re-checking the second read, leading to reading and writing control addresses and hijacking host control flow.
ReportedView cited source - [4]
Preconditions are that the host runs untrusted JavaScript inside isolated-vm and passes at least one ivm.Reference, and that the guest can reach ivm.Reference or an attacker-controlled transferList.
ReportedView cited source - [5]
Affected configurations are described as using isolated-vm version 7.0.0 or lower, or version 6.x below 6.2.0.
ReportedView cited source
Sources & coverage · 2 publishers
The reporting this story was synthesized from, earliest first. Every link goes to the original.
- dev.toAnoymaskyesterdayJavaScript Sandbox Escape via Type Confusion in isolated-vm
Cited in this coverage: Endor Labs advisory write-up as summarised on dev.to

