CVE-2026-93603
large1· 1 readvm2 Sandbox Escape in Bridge Apply Trap Leaks Host Global, Enabling Host RCE
vm2 through 3.12.0 does not correctly handle a nullish `this` receiver in the apply trap of its sandbox bridge (lib/bridge.js): when sandboxed code calls a host-provided non-strict (sloppy-mode) function without a receiver — e.g. `fn()`, a detached method, `fn.call()`, `fn.apply(undefined)`, `Reflect.apply(fn, undefined, [])`, or `fn.bind()()` — the undefined receiver reaches the host call and V8 substitutes the host realm's global object for `this`, which vm2 then wraps and returns to the sandbox as a live proxy of the host global. This constitutes a complete sandbox escape: untrusted script can reach `process` and execute arbitrary code or commands on the host, for example via `process.getBuiltinModule('child_process').execSync`. Exploitation requires that the embedding application expose at least one non-strict host function to the sandbox; strict-mode and ES module host functions are not affected. Any Node.js application or service that runs untrusted code in vm2 3.12.0 or earlier under those conditions is vulnerable. No public proof-of-concept or in-the-wild exploitation is currently known, and the issue is not in CISA KEV.
What to do: Upgrade vm2 to 3.12.1 or later. Where an immediate upgrade is not possible, audit every function exposed to the sandbox and ensure host callbacks are strict-mode (declared with 'use strict' or defined in ES modules) or stop passing host functions to untrusted script altogether. Teams running untrusted code in vm2 should also review sandbox entry points for detached-method call patterns that invoke host functions without a receiver.
| vm2 (node-vm2 project) vm2 Node.js sandbox library | through 3.12.0 (fixed in 3.12.1) |
Order-of-magnitude estimate by the model from install counts, market share and public scan data it knows; verify before quoting.
vm2 through 3.12.0 (fixed in 3.12.1) does not correctly handle a nullish `this` receiver in the apply trap of its bridge (lib/bridge.js): when sandboxed code calls a host-provided non-strict (sloppy-mode) function without a receiver — e.g. `fn()`, a detached method, `fn.call()`, `fn.apply(undefined)`, `Reflect.apply(fn, undefined, [])`, or `fn.bind()()` — the undefined receiver is passed straight through to the host call, and V8 substitutes the host realm's global object for `this`. vm2 then wraps and returns that object to the sandbox, giving sandboxed script a live proxy of the host global. This allows a complete sandbox escape: untrusted script can reach `process` and execute arbitrary code/commands on the host (for example via `process.getBuiltinModule('child_process').execSync`). Exploitation requires that the embedding application expose at least one non-strict host function to the sandbox; strict-mode and ES module host functions are not affected.
- Weakness
- CWE-94
- Vector
- CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
In the news0 stories
No ingested article mentions this CVE yet.