vm2 Native Code Execution via crypto.setEngine Sandbox Escape (CVE-2026-92939)
Detects exploitation and presence of CVE-2026-92939, a critical (CVSS 9.9, CWE-114 Process Control) sandbox escape in the vm2 npm package versions >= 3.11.3 and <= 3.11.6. The vm2 crypto builtin proxy fails to restrict the native `crypto.setEngine()` call, allowing untrusted code executing inside the vm2 sandbox to load an attacker-controlled native engine shared object (.so/.dll). Loading the native module executes attacker code outside the JavaScript sandbox with full host privileges of the Node.js process, resulting in remote code execution. A public PoC is available via GHSA-46pr-c5wc-xffx. This detection surfaces runtime indicators of the escape (Node.js processes loading unexpected native modules via OpenSSL engine loading, child process spawns from Node runtimes hosting vm2, and anomalous dlopen of untrusted shared objects) as well as software-inventory evidence of vulnerable vm2 versions. Remediate by upgrading to vm2 >= 3.11.7 or migrating off vm2 (the project is deprecated).
Vulnerability Intelligence
Public PoCAffected Software
- Vendor
- npm
- Product
- vm2
- Versions
- >= 3.11.3, <= 3.11.6
Weakness (CWE)
Timeline
- Disclosed
- October 1, 2026
References & Proof of Concept
- PoChttps://github.com/advisories/GHSA-46pr-c5wc-xffx
- https://github.com/patriksimek/vm2/security/advisories/GHSA-46pr-c5wc-xffx
- https://nvd.nist.gov/vuln/detail/CVE-2026-92939
- https://github.com/patriksimek/vm2/commit/aa146a77f859325e079f3bfbfe6d8309af483daa
- https://github.com/patriksimek/vm2/releases/tag/v3.11.7
- https://www.vulncheck.com/advisories/vm2-3.11.3-through-3.11.6-native-code-execution-via-crypto-setengine
CVSS
What is CVE-2026-92939 vm2 Native Code Execution via crypto.setEngine Sandbox Escape (CVE-2026-92939)?
vm2 Native Code Execution via crypto.setEngine Sandbox Escape (CVE-2026-92939) (CVE-2026-92939) 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 Native Code Execution via crypto.setEngine Sandbox Escape (CVE-2026-92939), 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
// CVE-2026-92939 - vm2 crypto.setEngine native code execution
// Surface Node.js processes loading native engine modules or spawning children (escape payload)
let nodeProcs = DeviceProcessEvents
| where Timestamp > ago(7d)
| where FileName in~ ("node", "node.exe", "nodejs");
// Child process spawned by a node process == strong post-escape signal for a pure-JS workload
DeviceProcessEvents
| where Timestamp > ago(7d)
| where InitiatingProcessFileName in~ ("node", "node.exe", "nodejs")
| where FileName in~ ("sh", "bash", "cmd.exe", "powershell.exe", "pwsh", "gcc", "cc", "ld", "openssl", "whoami", "id", "curl", "wget")
| project Timestamp, DeviceName, AccountName, InitiatingProcessFileName, InitiatingProcessCommandLine, FileName, ProcessCommandLine, FolderPath
| union (
DeviceImageLoadEvents
| where Timestamp > ago(7d)
| where InitiatingProcessFileName in~ ("node", "node.exe", "nodejs")
| where FileName endswith ".so" or FileName endswith ".dll" or FileName endswith ".node"
| where not(FolderPath has_any ("node_modules", "\\nodejs\\", "/usr/lib/node", "/usr/local/lib/node"))
| project Timestamp, DeviceName, AccountName=InitiatingProcessAccountName, InitiatingProcessFileName, InitiatingProcessCommandLine, FileName, FolderPath
)
| order by Timestamp desc Flags Node.js processes that spawn shell/compiler/recon child processes or load native modules (.so/.dll/.node) from paths outside standard Node runtime directories — the observable result of a vm2 setEngine escape loading attacker native code.
Data Sources
Required Tables
False Positives
- Node.js applications that legitimately use native addons (node-gyp built .node modules) loaded from non-standard build directories
- Build/CI agents where node legitimately invokes gcc/cc/ld during npm install of native dependencies
- Monitoring or APM agents that inject native profiling libraries into the Node process
Sigma rule & cross-platform mapping
The detection logic for vm2 Native Code Execution via crypto.setEngine Sandbox Escape (CVE-2026-92939) (CVE-2026-92939) 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-92939
References (6)
- https://github.com/patriksimek/vm2/security/advisories/GHSA-46pr-c5wc-xffx
- https://nvd.nist.gov/vuln/detail/CVE-2026-92939
- https://github.com/patriksimek/vm2/commit/aa146a77f859325e079f3bfbfe6d8309af483daa
- https://github.com/patriksimek/vm2/releases/tag/v3.11.7
- https://www.vulncheck.com/advisories/vm2-3.11.3-through-3.11.6-native-code-execution-via-crypto-setengine
- https://github.com/advisories/GHSA-46pr-c5wc-xffx
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 1Install vulnerable vm2 version (inventory detection)
Expected signal: npm install process events, file creation under /tmp/vm2-cve/node_modules/vm2, node process reading package.json
- Test 2Node process spawns shell child (escape payload simulation)
Expected signal: auditd execve showing node as parent of sh/id; Sysmon-equivalent process creation
- Test 3Node loads untrusted native module (dlopen simulation)
Expected signal: node process image/library load of /tmp/evil_engine.so outside node_modules; appears in /proc/<pid>/maps
Response Playbook
Triage
- Confirm the host runs a Node.js application that embeds the vm2 package and determine its version via `npm ls vm2` / inspection of package-lock.json; versions >= 3.11.3 and <= 3.11.6 are vulnerable to CVE-2026-92939.
- Correlate the alerting Node.js process with the application it serves and establish whether that application accepts and evaluates untrusted/user-supplied JavaScript inside vm2 (the required precondition for exploitation).
- Examine the child process or loaded native module path flagged by the alert: determine whether the .so/.dll/.node file is a legitimate npm native addon or an attacker-staged artifact, including its on-disk location, hash, and signer.
- Review the parent Node process command line and recent application logs for the crypto.setEngine call pattern or errors referencing OpenSSL engine loading.
Containment
- Isolate the affected host from the network to prevent lateral movement and C2 from the escaped native payload.
- Kill the offending Node.js process and any child processes it spawned, and disable the service/pod until vm2 is upgraded to >= 3.11.7 or removed.
- Quarantine the suspicious native module/shared object and block its hash across the fleet.
Evidence Collection
- Capture the Node.js process memory and the full process tree (parent node + all children) before termination for forensic analysis.
- Collect the suspect native engine file (.so/.dll/.node), its filesystem metadata (timestamps, ownership), and compute cryptographic hashes.
- Preserve application and reverse-proxy logs showing the request/payload that reached the vm2 sandbox, plus package-lock.json documenting the vulnerable vm2 version.
Escalation Criteria
- ! Escalate to incident response if a non-npm, unsigned native module was loaded by the Node process or if any child process performed reconnaissance, credential access, or outbound network connections.
- ! Escalate if the affected application is internet-facing and accepts untrusted code, indicating probable active exploitation rather than a false positive.
- ! Escalate to threat hunting if the same native-module-load or node-spawns-shell pattern appears on multiple hosts.
Investigation Guide
Forensic Artifacts
- >
The attacker-supplied native engine shared object (.so/.dll/.node) on disk and its load entry in /proc/<pid>/maps or Sysmon ImageLoad events - >
package-lock.json / node_modules/vm2/package.json showing version 3.11.3–3.11.6 - >
Application logs or stack traces referencing crypto.setEngine or OpenSSL ENGINE_by_id loading - >
Node.js process tree showing child processes uncharacteristic of a pure-JS workload
Tuning Guidance
Baseline which Node.js applications legitimately spawn child processes or load native addons (node-gyp .node modules) and allowlist those specific parent application paths and module directories. Restrict the match to production application hosts and exclude CI/build agents where gcc/cc/ld invocation by node during npm install is expected. Prioritize alerts where the loaded native module resides outside node_modules or is unsigned/unknown-hash, as those are the strongest escape indicators.
Hunting Queries
Hunts for Node.js processes spawning shells, compilers, or recon tooling across the fleet, surfacing vm2 escape activity beyond the initial alert.
DeviceProcessEvents | where InitiatingProcessFileName in~ ("node","node.exe","nodejs") | where FileName in~ ("sh","bash","openssl","gcc","cc","whoami","id","curl","wget") | summarize count() by DeviceName, FileName, ProcessCommandLine, bin(Timestamp,1h) index=* sourcetype="WinEventLog:Sysmon" OR sourcetype="linux:audit" | eval p=lower(coalesce(ParentImage,parent_process_name)) | where like(p,"%node%") | stats count values(Image) as children by host,user Atomic Red Team Tests
Installs vm2 3.11.6 to generate software-inventory evidence of the vulnerable version range for CVE-2026-92939.
Command
mkdir -p /tmp/vm2-cve && cd /tmp/vm2-cve && npm init -y >/dev/null 2>&1 && npm install [email protected] >/dev/null 2>&1 && node -e "console.log(require('/tmp/vm2-cve/node_modules/vm2/package.json').version)" Cleanup
rm -rf /tmp/vm2-cve Expected Telemetry
npm install process events, file creation under /tmp/vm2-cve/node_modules/vm2, node process reading package.json
Expected Detection
Software inventory / SCA flags [email protected] as within affected range >=3.11.3,<=3.11.6.
Simulates the post-escape behavior where native code loaded via setEngine spawns a host shell from the Node.js process.
Command
node -e "require('child_process').execSync('id > /tmp/vm2_escape_proof.txt')" Cleanup
rm -f /tmp/vm2_escape_proof.txt Expected Telemetry
auditd execve showing node as parent of sh/id; Sysmon-equivalent process creation
Expected Detection
Alert fires on Node.js parent spawning shell/recon child process.
Simulates loading an attacker-staged native engine module from a non-standard path, mimicking crypto.setEngine native code loading.
Command
cp /usr/lib/x86_64-linux-gnu/libz.so.1 /tmp/evil_engine.so 2>/dev/null; node -e "try{process.dlopen({exports:{}},'/tmp/evil_engine.so')}catch(e){console.log('load attempted:',e.message)}" Cleanup
rm -f /tmp/evil_engine.so Expected Telemetry
node process image/library load of /tmp/evil_engine.so outside node_modules; appears in /proc/<pid>/maps
Expected Detection
Alert fires on Node.js loading a native .so from an untrusted path outside standard runtime directories.