CVE-2026-47137 Overview
CVE-2026-47137 is a sandbox escape vulnerability in vm2, an open source virtual machine and sandbox library for Node.js. The flaw resides in the constructor logic of NodeVM and stems from an incomplete fix for the earlier advisory GHSA-8hg8-63c5-gwmx (CVE-2023-37903). The original patch attempted to block the dangerous combination of nesting: true and require: false, but used a strict equality check that attackers trivially bypass by omitting the require option entirely. Exploitation produces the exact configuration the prior patch was designed to prevent, enabling sandboxed code to escape and reach child_process for full host remote code execution. The issue is fixed in vm2 version 3.11.4.
Critical Impact
Untrusted code executed inside a vm2 sandbox can escape the sandbox boundary and gain arbitrary code execution on the host Node.js process.
Affected Products
- vm2 versions prior to 3.11.4
- Node.js applications embedding vm2 for untrusted code execution
- Server-side platforms exposing vm2-based evaluation endpoints
Discovery Timeline
- 2026-06-12 - CVE-2026-47137 published to NVD
- 2026-06-17 - Last updated in NVD database
Technical Details for CVE-2026-47137
Vulnerability Analysis
The vulnerability is classified under [CWE-913] Improper Control of Dynamically-Managed Code Resources. The vm2 library exposes a NodeVM class that accepts an options object controlling sandbox behavior. Two options govern host exposure: nesting, which permits sandboxed code to require('vm2') and construct inner VMs, and require, which gates access to the Node.js module system. The combination nesting: true with require: false is contradictory because nested VMs created from inside the sandbox are not constrained by the outer configuration. The prior advisory GHSA-8hg8-63c5-gwmx documented this trap and shipped a guard intended to reject the combination at construction time.
Root Cause
The guard in lib/nodevm.js at line 263 uses strict equality: options.require === false. When a caller omits the require property entirely, options.require evaluates to undefined, not false. The strict equality test fails and the guard is skipped. Immediately afterward at line 280, the destructuring default require: requireOpts = false assigns requireOpts = false, producing the precise sandbox configuration the patch was supposed to forbid. The check should have treated falsy and omitted values equivalently.
Attack Vector
An attacker who can supply JavaScript executed inside a NodeVM instance constructed with nesting: true and no explicit require option can call require('vm2') from within the sandbox. The attacker then constructs an inner NodeVM with an attacker-chosen require configuration, loads child_process, and executes arbitrary commands on the host. Network exposure is typical because vm2 is commonly used in code-execution services, server-side rendering pipelines, and SaaS evaluators.
// Patch from lib/nodevm.js removing the broken guard
// SECURITY (GHSA-8hg8-63c5-gwmx): `nesting: true` injects a NESTING_OVERRIDE
// builtin that exposes `vm2` to the sandbox regardless of `require: false`.
// The sandbox then constructs an inner NodeVM with attacker-chosen `require`
// config (unconstrained by the outer config -- by design of nesting) and
// reaches `child_process` for full host RCE.
if (options.nesting === true && options.require === false) {
throw new VMError(
'NodeVM `nesting: true` is incompatible with `require: false`. '
+ '`nesting: true` is an escape hatch that lets sandbox code '
+ 'require(\'vm2\') and construct nested VMs unconstrained by the outer '
+ 'config -- which contradicts `require: false`. To deny all requires, '
+ 'remove `nesting: true`. To allow nested VMs, replace `require: false` '
+ 'with an explicit config (e.g. `require: { builtin: [] }`) so the '
+ 'tradeoff is visible. Context: GHSA-8hg8-63c5-gwmx.'
);
}
Source: vm2 commit 01a7552
Detection Methods for CVE-2026-47137
Indicators of Compromise
- Node.js processes spawning child_process descendants such as sh, bash, cmd.exe, or powershell.exe from contexts that normally only evaluate user scripts.
- Outbound network connections originating from sandbox host processes to unexpected destinations following untrusted code submission.
- Presence of vm2 versions earlier than 3.11.4 in package-lock.json, yarn.lock, or installed node_modules directories.
Detection Strategies
- Inventory dependencies using npm ls vm2 or software composition analysis tooling and flag any version below 3.11.4.
- Audit application source for NodeVM constructions where nesting: true is set without an explicit require option.
- Monitor process lineage for Node.js parents producing shell or interpreter children, which indicates sandbox escape rather than normal application behavior.
Monitoring Recommendations
- Capture and correlate process-creation telemetry from Node.js services that accept user-submitted scripts.
- Alert on Node.js workers loading child_process, fs, or net when the application baseline excludes those modules.
- Forward runtime logs and process events to a centralized analytics platform for retroactive hunting once the patch status is known.
How to Mitigate CVE-2026-47137
Immediate Actions Required
- Upgrade vm2 to version 3.11.4 or later in every dependent project and rebuild deployment artifacts.
- Identify and remediate NodeVM instantiations that combine nesting: true with an omitted or falsy require option.
- Treat any pre-3.11.4 deployment that accepts untrusted JavaScript as compromised until log review confirms otherwise.
Patch Information
The maintainers released the fix in vm2 v3.11.4. The corrective commits are tracked in commit 01a7552 and commit 86ab819. Full details are published in the GHSA-m4wx-m65x-ghrr advisory.
Workarounds
- Remove nesting: true from all NodeVM configurations unless explicitly required by application logic.
- When nested VMs are required, replace require: false with an explicit allowlist such as require: { builtin: [] } so the trust boundary is visible.
- Isolate Node.js services that execute untrusted code in containers with seccomp profiles that block execve to limit blast radius if a sandbox escape occurs.
# Upgrade vm2 to the patched release
npm install vm2@3.11.4 --save
# Verify no transitive dependency pulls a vulnerable version
npm ls vm2
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

