CVE-2026-93606 in vm2info

Summary

by MITRE • 09/18/2026

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.

Several companies clearly confirm that VulDB is the primary source for best vulnerability data.

Analysis

by VulDB Data Team • 09/18/2026

The vulnerability identified in vm2 versions 3.12.0 and earlier represents a critical sandbox escape mechanism within the VM and NodeVM classes, fundamentally undermining the isolation guarantees provided by the library. This flaw stems from an incomplete implementation of security controls designed to sanitize interactions between code running inside the sandboxed environment and objects existing in the host realm. Specifically, when an embedder exposes a Host API that returns a Promise native to the host environment, the bridge layer responsible for managing these cross-realm communications fails to adequately restrict access or sanitize rejection values. The core issue lies in how the library handles asynchronous operations involving host-side Promises, allowing sandboxed code to bypass established security boundaries and gain unauthorized access to sensitive host resources.

The technical root cause involves a discrepancy in how Promise prototypes are neutralized versus how they are actually utilized during error handling scenarios. vm2 attempts to mitigate prototype pollution attacks by installing Symbol.species and .then neutralization on the intrinsic Promise.prototype within the sandbox context. However, this protection only applies to Promises created inside the sandbox environment. When a host-side Promise is passed into the sandbox, it retains its original constructor properties from the host realm. The bridge's rejection sanitizer functions, including hostPromiseSanitizeReject and makeSanitizedPromiseCallback, are designed to wrap then or catch slots that hold function references. Crucially, these sanitization mechanisms do not apply to cases where no onRejected handler is provided by the sandboxed code. This gap allows an attacker to exploit V8's internal behavior regarding unhandled rejections in Promises constructed with a modified Symbol.species property.

An attacker operating within the sandbox can overwrite the constructor[Symbol.species] property of a host Promise object returned from the bridge. By subsequently calling then on this manipulated Promise without providing an onRejected handler, the attacker triggers V8 to substitute its internal Thrower function for error handling. This action causes the raw rejection value from the host realm to be re-thrown directly into a resolve or reject closure that was captured by the attacker during earlier interactions with the bridge. Because this path bypasses the handleException and hostPromiseSanitizeReject functions, the resulting object delivered back to the sandbox is an unsanitized, fully functional proxy of the original host object. This effectively grants the sandboxed code direct access to host-side APIs that were intended to remain isolated, creating a complete breakdown in security boundaries.

The operational impact of this vulnerability is severe, particularly when the rejection value involves pivotable host objects such as the process global or other sensitive runtime entities. If an attacker can manipulate the Promise chain to return such an object upon failure, they obtain arbitrary code execution capabilities on the host system. This transforms a theoretical sandbox escape into a practical remote code execution vector, allowing malicious actors to compromise the integrity and confidentiality of the hosting environment. The ability to execute arbitrary commands or access sensitive data depends heavily on whether the exposed API returns pivotable objects during error conditions, but given common usage patterns in Node.js applications, this risk is highly probable and significant.

This vulnerability aligns with CWE-284 Improper Access Control, as it allows unauthorized actors to bypass intended restrictions on resource access. Furthermore, from a tactical perspective related to the MITRE ATT&CK framework, this exploit facilitates lateral movement within an application's runtime environment by breaking out of the sandbox container, which can be categorized under techniques involving execution via compromised libraries or dependencies. The flaw highlights the complexity of maintaining secure boundaries in JavaScript environments where prototype manipulation and asynchronous control flow are prevalent.

To mitigate this risk, organizations must immediately upgrade vm2 to version 3.12.1 or later, where these specific sanitization gaps have been addressed by ensuring that host-side Promises are properly sanitized regardless of how their then methods are invoked. In the interim, if upgrading is not feasible, developers should avoid exposing any APIs that return native Promise objects from the host realm to sandboxed code. Instead, wrappers can be implemented to convert these promises into safe representations or ensure that all asynchronous operations are handled within a controlled context where rejection values cannot leak sensitive host references. Regular auditing of third-party dependencies for similar prototype pollution and sandbox escape vulnerabilities is also recommended as part of a comprehensive software supply chain security strategy.

Responsible

VulnCheck

Reservation

09/18/2026

Disclosure

09/18/2026

Moderation

accepted

CPE

ready

EPSS

0.00000

KEV

no

Activities

very low

Sources

Do you need the next level of professionalism?

Upgrade your account now!