Detect vm2 Sandbox Escape via WebAssembly.compileStreaming Promise Species Bypass (CVE-2026-92956) in Google Chronicle
Detects exploitation and presence of CVE-2026-92956, a critical (CVSS 10.0) sandbox escape in the vm2 npm package (>= 3.10.1, <= 3.11.6). The flaw abuses WebAssembly.compileStreaming, which internally resolves a user-controllable Promise. By overriding the Promise's Symbol.species constructor, untrusted code running inside the vm2 sandbox obtains a reference to a host-realm Promise and uses it to reach the host's unproxied objects, escaping the sandbox and achieving arbitrary code execution on the Node.js host (CWE-693 Protection Mechanism Failure, CWE-913 Improper Control of Dynamically-Managed Code Resources). Because vm2 is widely embedded to execute third-party/untrusted JavaScript, this detection focuses on identifying vulnerable installed versions, suspicious sandbox-escape payload patterns, and post-escape child-process / filesystem / network activity spawned from a Node.js process hosting vm2. Fixed in vm2 3.11.7.
MITRE ATT&CK
- Tactic
- Execution Defense Evasion
YARA-L Detection Query
rule vm2_cve_2026_92956_sandbox_escape {
meta:
author = "argus"
description = "vm2 sandbox escape via WebAssembly.compileStreaming Promise species bypass (CVE-2026-92956)"
severity = "CRITICAL"
cve = "CVE-2026-92956"
events:
$e.metadata.event_type = "PROCESS_LAUNCH"
re.regex($e.principal.process.parent_process.file.full_path, `(?i)node(\.exe)?$`)
(
re.regex($e.principal.process.file.full_path, `(?i)(cmd\.exe|powershell|pwsh|/sh|/bash|curl|wget|whoami|ncat?)`)
)
(
re.regex($e.principal.process.command_line, `(?i)(compileStreaming|Symbol\.species|child_process|base64)`) or
re.regex($e.principal.process.parent_process.command_line, `(?i)(vm2|compileStreaming)`)
)
condition:
$e
} Chronicle YARA-L 2.0 rule detecting Node.js (vm2 host) process launches spawning shell/recon binaries with vm2 compileStreaming sandbox-escape markers.
Data Sources
Required Tables
False Positives & Tuning
- Node CI/CD runners forking shell steps
- Node applications using child_process by design
- Admin automation launched from Node that calls network utilities
Other platforms for CVE-2026-92956
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 1Enumerate installed vm2 version for CVE-2026-92956 exposure
Expected signal: npm install network/file activity creating node_modules/vm2 with package.json version 3.11.6; node process reading the vm2 package.json.
- Test 2Simulate vm2 sandbox escape spawning a child process
Expected signal: node process spawns /bin/sh -> whoami and writes /tmp/vm2_escape_poc.txt.
- Test 3Payload marker in submitted script (WebAssembly.compileStreaming)
Expected signal: node process command line referencing /tmp/vm2_species_poc.js; file creation of the script containing compileStreaming and Symbol.species strings.
References (7)
- https://github.com/patriksimek/vm2/security/advisories/GHSA-wjwh-qqvp-g4p4
- https://nvd.nist.gov/vuln/detail/CVE-2026-92956
- https://github.com/patriksimek/vm2/commit/cb85599e4470afa308e7c807b5c6b3ec9bf58b18
- https://github.com/patriksimek/vm2/blob/415339f698f0d52d3c5ad358b12b79c8072d5b4b/lib/setup-sandbox.js#L510-L523
- https://github.com/patriksimek/vm2/releases/tag/v3.11.7
- https://www.vulncheck.com/advisories/vm2-3.10.1-through-3.11.6-sandbox-escape-via-webassembly-compilestreaming
- https://github.com/advisories/GHSA-wjwh-qqvp-g4p4
Response Playbook
Triage
- Confirm the affected host runs a Node.js application that embeds vm2; inventory the installed version with `npm ls vm2` / inspect package-lock.json and flag any version >= 3.10.1 and <= 3.11.6 as vulnerable (fixed in 3.11.7).
- Review the alerting Node process's parent/child tree and command lines for WebAssembly.compileStreaming, Symbol.species/constructor overrides, or child_process usage indicating a sandbox-escape payload.
- Determine whether the vm2 instance executes untrusted/third-party JavaScript (e.g., user-submitted code, plugins, serverless functions); untrusted-input exposure sharply raises exploit likelihood.
- Correlate the timeframe of the suspicious child process with recent inbound requests or job submissions that could carry the malicious script.
Containment
- Isolate the affected host from the network to prevent post-escape lateral movement and C2 while investigation proceeds.
- Stop or disable the Node.js service hosting vm2, or patch vm2 to 3.11.7+ immediately before restarting; if patching is not possible, block submission of untrusted code paths.
- Rotate any secrets, tokens, or credentials accessible to the Node.js process, as a successful escape yields full host code execution.
Evidence Collection
- Capture the full process tree, command lines, and loaded modules for the Node.js host and all spawned children (EDR timeline export).
- Preserve application logs and any stored/submitted script payloads, plus package-lock.json / node_modules/vm2/package.json to prove the vulnerable version.
Escalation Criteria
- !Escalate to IR immediately if a Node.js (vm2) process spawned an OS shell, downloaded tooling, or established outbound connections — this indicates a successful escape and host compromise.
- !Escalate if the vulnerable vm2 version is confirmed on an internet-exposed service that accepts untrusted code, regardless of whether exploitation telemetry is yet observed.
Investigation Guide
Related Techniques
Forensic Artifacts
- >
node_modules/vm2/package.json version field (and package-lock.json) confirming an affected 3.10.1–3.11.6 install - >
Process-creation telemetry showing a node parent spawning shells, interpreters, or network utilities - >
Stored request/job payloads containing WebAssembly.compileStreaming and Symbol.species/constructor overrides
Tuning Guidance
Baseline which Node.js services on your estate legitimately spawn child processes (build agents, media processors, serverless workers) and exclude those parent command lines or hosts. Tighten by requiring co-occurrence of compileStreaming/Symbol.species markers for high-confidence alerts, and prioritize hosts where vm2 version is confirmed in the vulnerable range and executes untrusted input.
Hunting Queries
Surfaces all Node.js processes spawning OS shells or recon/download tools so analysts can review for vm2 post-escape execution even without payload markers.
DeviceProcessEvents | where InitiatingProcessFileName in~ ("node.exe","node") | where FileName in~ ("cmd.exe","powershell.exe","bash","sh","curl","wget","whoami") | project Timestamp, DeviceName, InitiatingProcessCommandLine, FileName, ProcessCommandLine | order by Timestamp desc index=* (ParentImage="*node*") (Image="*cmd.exe*" OR Image="*powershell*" OR Image="*/sh" OR Image="*/bash" OR Image="*curl*" OR Image="*wget*") | table _time host ParentCommandLine Image CommandLine Atomic Red Team Tests
Checks whether a vulnerable vm2 version (>=3.10.1, <=3.11.6) is installed in a Node project, which is the prerequisite for exploitation.
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/file activity creating node_modules/vm2 with package.json version 3.11.6; node process reading the vm2 package.json.
Expected Detection
Version inventory flags vm2 3.11.6 as within the affected range for CVE-2026-92956.
Lab-only simulation that runs code inside a vm2 sandbox which escapes and executes a benign OS command, mimicking the post-escape process-spawn telemetry of CVE-2026-92956.
Command
cd /tmp && npm install [email protected] >/dev/null 2>&1 && node -e "const {VM}=require('/tmp/node_modules/vm2');try{new VM().run('process');}catch(e){};require('child_process').execSync('whoami > /tmp/vm2_escape_poc.txt')" Cleanup
rm -f /tmp/vm2_escape_poc.txt && rm -rf /tmp/node_modules /tmp/package.json /tmp/package-lock.json Expected Telemetry
node process spawns /bin/sh -> whoami and writes /tmp/vm2_escape_poc.txt.
Expected Detection
Rule fires on a node parent process launching a shell/whoami child indicative of post-escape command execution.
Writes and executes a Node script containing the compileStreaming / Symbol.species markers used by the public PoC, generating detectable command-line and file artifacts.
Command
printf '%s\n' "const p = Promise.resolve(); p.constructor = function(){}; p.constructor[Symbol.species] = function(){}; try { WebAssembly.compileStreaming(p); } catch(e){ console.log('compileStreaming species test executed'); }" > /tmp/vm2_species_poc.js && node /tmp/vm2_species_poc.js Cleanup
rm -f /tmp/vm2_species_poc.js Expected Telemetry
node process command line referencing /tmp/vm2_species_poc.js; file creation of the script containing compileStreaming and Symbol.species strings.
Expected Detection
Command-line/file content detection matches on compileStreaming and Symbol.species sandbox-escape markers.