VYPR
Vypr IntelligenceAI-generatedMay 31, 2026· 10 CVEs

vm2: Nine Sandbox Escape CVEs Disclosed in a Single-Day Advisory

Nine critical and high-severity vulnerabilities in the vm2 Node.js sandbox library were disclosed on May 29, 2026, including bypasses of prior patches and novel escape vectors via JSPI, Promise species, and unblocked builtins.

Key findings

  • Nine CVEs disclosed on May 29, 2026, spanning critical sandbox escapes to high-severity bypasses
  • CVE-2026-47210 exploits WebAssembly JSPI for the first documented vm2 escape via that API
  • CVE-2026-47137 is a trivial bypass of the CVE-2023-37903 patch using omitted require option
  • CVE-2026-47140: process and inspector/promises are missing from the builtin denylist
  • CVE-2026-47209 and CVE-2026-47135 exploit Proxy trap and cross-realm symbol weaknesses
  • CVE-2026-47141 exposes host process data via unblocked diagnostics_channel and async_hooks

On May 29, 2026, nine security vulnerabilities in the vm2 Node.js sandbox library (maintained by Patriksimek) were disclosed within a one-hour window, spanning critical sandbox escapes, builtin denylist bypasses, and proxy-trap logic flaws. The batch includes three CVEs rated critical and three rated high, making it one of the most significant disclosure events for the library since the CVE-2023-37903 patch saga. vm2 is widely used to run untrusted JavaScript in isolated environments on Node.js servers, and these flaws collectively demonstrate that the sandbox's security boundaries remain porous across multiple attack surfaces.

Critical Sandbox Escapes: Full Host Code Execution

Three of the disclosed CVEs carry a critical severity rating and represent direct sandbox escape paths to arbitrary code execution on the host.

CVE-2026-47210 exploits a novel vector involving WebAssembly JavaScript Promise Integration (JSPI). On runtimes where WebAssembly.promising and WebAssembly.Suspending are available, a JSPI-backed Promise can reach Promise.prototype.finally() through a species bypass, allowing sandboxed code to escape into the host process. This is the first documented vm2 escape leveraging the JSPI API surface.

CVE-2026-47208 describes a sandbox breakout through the Promise species mechanism. The localPromise constructor in vm2 was changed to call this.then(undefined, eater) for rejected promise handling, but this opened a path for attackers to write code that escapes the sandbox and executes arbitrary commands on the host system.

CVE-2026-47131 chains Buffer.call.call({}.__lookupGetter__, Buffer, "__proto__") and Buffer.call.call({}.__lookupSetter__, Buffer, "__proto__") with Node.js's ERR_INVALID_ARG_TYPE Error to obtain the host's TypeError constructor, which then enables full sandbox escape and arbitrary code execution.

Patch Bypass: CVE-2023-37903 Fix Circumvented

CVE-2026-47137 is a direct bypass of the fix for CVE-2023-37903 (GHSA-8hg8-63c5-gwmx). The original patch introduced a check in nodevm.js at line 263 that blocks the combination nesting: true with require: false. However, the check uses strict equality (options.require === false), which is trivially bypassed by simply omitting the require option entirely. When require is undefined, the check passes, and the sandbox can be configured with nesting: true without explicit require restrictions, enabling full remote code execution. This CVE is rated critical.

Builtin Denylist and Network Exclusion Bypasses

CVE-2026-47140 (critical) targets the builtin denylist. While vm2 blocks dangerous builtins such as module, worker_threads, cluster, vm, repl, and inspector, the denylist misses process and inspector/promises. Both can be used from sandboxed code to reach host-side execution primitives, bypassing the sandbox entirely.

CVE-2026-47139 (high) addresses a bypass of network builtin exclusions. vm2 supports excluding public network builtins (http, https, http2, net, dgram, tls, dns, dns/promises) from the wildcard builtin option. However, Node.js also exposes underscored internal HTTP builtins such as _http_client and _http_server, which are not blocked and can be used to reach the network layer.

CVE-2026-47141 (severity not rated but functionally significant) reveals that NodeVM exposes process-wide observability builtins — diagnostics_channel, async_hooks, and perf_hooks — when allowed through require.builtin. These modules are process-wide, not sandbox-local, meaning sandboxed code can leak host process and HTTP request data.

Proxy Trap and Cross-Realm Symbol Flaws

CVE-2026-47209 (high) identifies a flaw in the BaseHandler.set trap in bridge.js (line 1231). The trap ignores the receiver parameter and unconditionally writes to the host target object. Per the Proxy set trap specification, when receiver !== proxy (e.g., when a child object inherits from the proxy via Object.create), the property assignment should be directed to the receiver, not the target. This enables host object property injection via the prototype chain.

CVE-2026-47135 (high) combines two weaknesses: vm2's Symbol.for override in setup-sandbox.js only intercepts 2 of 9 dangerous Node.js cross-realm symbols, and the bridge's set/defineProperty/deleteProperty traps have no isDangerousCrossRealmSymbol key check. Sandbox code can obtain real cross-realm symbols, write them to host objects, and escape the sandbox.

Response and Mitigation

As of the disclosure date, users of vm2 should treat all versions prior to the forthcoming patched release as vulnerable to one or more of these CVEs. Given the critical severity of multiple escape vectors — especially CVE-2026-47210 (JSPI), CVE-2026-47208 (Promise species), CVE-2026-47140 (process/inspector/promises), and CVE-2026-47137 (patch bypass) — immediate mitigation is essential. Users who cannot immediately patch should consider disabling async support, restricting require.builtin to an empty allowlist, and avoiding the nesting: true configuration entirely.

Why This Batch Matters

This disclosure event underscores a recurring theme in sandbox security: each patch creates new surface for bypasses, and the complexity of Node.js's runtime — with its internal modules, Promise mechanics, WebAssembly integration, and Proxy semantics — provides an ever-expanding attack surface. For teams running vm2 in production to isolate untrusted code (e.g., in REPL environments, code-execution platforms, or plugin systems), this batch of nine CVEs is a strong signal that the library's security model requires careful configuration and vigilant patching.

AI-written article. Grounded in 10 CVE records listed below.