CVE-2026-93606: vm2 before 3.12.1 Sandbox Escape via Promise Symbol.species
vm2 (npm) versions 3.12.0 and earlier contain a sandbox escape in VM and NodeVM. When an embedder exposes a host API that returns a host-realm Promise, the bridge's rejection sanitizer (hostPromiseSanitizeReject / makeSanitizedPromiseCallback / normalizeHostPromiseCallbacks in lib/bridge.js) only wraps then/catch rejection slots that hold a function, and the sandbox-side Symbol.species/.then neutralization is installed only on the sandbox intrinsic Promise.prototype, so it never applies to a host Promise. Code running inside the sandbox can overwrite p.constructor[Symbol.species] on the host Promise and then call p.then() with no onRejected handler; V8 substitutes its internal Thrower, which re-throws the raw host rejection value into a resolve/reject closure captured by the attacker. This delivers an unsanitized, fully functional bridge proxy of the host object to sandboxed code, bypassing handleException and hostPromiseSanitizeReject. If the rejection value is host-pivotable (for example a host process object), this results in arbitrary code execution on the host. Fixed in 3.12.1.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
vm2 (npm)to a version that resolves this vulnerability.Fixed in 3.12.1 - Compensating control
Ensure sandboxed code cannot pivot host-realm rejection values to attacker-controlled data; for example, avoid exposing host APIs to the sandbox that return host-realm Promises with rejection values that could be host objects (host-pivotable), such as a host `process` object.
Event History
Frequently Asked Questions
Which deployments are exposed to host code execution?
Deployments using vm2 3.12.0 or earlier are exposed when sandboxed code can receive a host-realm Promise from an API exposed by the embedder. Host code execution requires that the Promise reject with a host object that can be used as a pivot, such as a host process object.
Does exploitation require credentials or user interaction?
No. The supplied severity vector indicates network access, low attack complexity, no privileges, and no user interaction, but the attacker must be able to execute code in the vm2 sandbox and reach an exposed API returning a host Promise.
What should be done if upgrading cannot happen immediately?
Do not expose host APIs that return host-realm Promises to untrusted vm2 code, especially where rejected values may contain host-pivotable objects. This reduces exposure to the described escape path until vm2 can be updated to 3.12.1.
How can I determine whether my integration is affected?
Check whether the application uses vm2 3.12.0 or earlier and whether either VM or NodeVM exposes host APIs to sandboxed code. Review those APIs for returned native host Promises and for rejection values that expose functional host objects.