CVE-2026-92956 Microsoft Sentinel · KQL

Detect vm2 Sandbox Escape via WebAssembly.compileStreaming Promise Species Bypass (CVE-2026-92956) in Microsoft Sentinel

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

KQL Detection Query

Microsoft Sentinel (KQL)
kusto
// CVE-2026-92956 - vm2 sandbox escape via WebAssembly.compileStreaming Promise species bypass
// Hunt 1: Node.js host processes spawning suspicious children immediately after executing sandboxed code
let suspiciousChildren = dynamic(["cmd.exe","powershell.exe","pwsh.exe","bash","sh","/bin/sh","/bin/bash","curl","wget","nc","ncat","whoami","certutil.exe"]);
DeviceProcessEvents
| where InitiatingProcessFileName in~ ("node.exe","node")
| where FileName has_any (suspiciousChildren)
| where ProcessCommandLine has_any ("compileStreaming","Symbol.species","constructor","-c ","IEX","base64","child_process","spawn","exec")
    or InitiatingProcessCommandLine has_any ("vm2","compileStreaming")
| project Timestamp, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, FileName, ProcessCommandLine, AccountName, InitiatingProcessId
| order by Timestamp desc
critical severity medium confidence

Flags Node.js processes (common vm2 hosts) spawning OS command interpreters or recon/download tools, correlated with WebAssembly.compileStreaming / Promise species payload markers indicative of a vm2 sandbox escape.

Data Sources

Microsoft Defender for EndpointDeviceProcessEvents

Required Tables

DeviceProcessEvents

False Positives & Tuning

  • Legitimate Node.js build tooling or CI runners that spawn shell commands as part of normal scripts
  • Node-based application servers that intentionally execute child processes (e.g., image processing wrappers)
  • Developer workstations running local scripts that invoke curl/wget from Node

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.

  1. 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.

  2. Test 2Simulate vm2 sandbox escape spawning a child process

    Expected signal: node process spawns /bin/sh -> whoami and writes /tmp/vm2_escape_poc.txt.

  3. 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.


Response Playbook

Triage

  1. 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).
  2. 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.
  3. 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.
  4. Correlate the timeframe of the suspicious child process with recent inbound requests or job submissions that could carry the malicious script.

Containment

  1. Isolate the affected host from the network to prevent post-escape lateral movement and C2 while investigation proceeds.
  2. 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.
  3. Rotate any secrets, tokens, or credentials accessible to the Node.js process, as a successful escape yields full host code execution.

Evidence Collection

  1. Capture the full process tree, command lines, and loaded modules for the Node.js host and all spawned children (EDR timeline export).
  2. 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.

Hunting — KQL
kql
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
Hunting — SPL
spl
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

Test 1 Enumerate installed vm2 version for CVE-2026-92956 exposure
linux

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

bash
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

bash
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.

Test 2 Simulate vm2 sandbox escape spawning a child process
linux

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

bash
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

bash
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.

Test 3 Payload marker in submitted script (WebAssembly.compileStreaming)
linux

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

bash
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

bash
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.

Related Detections