SECURITYCRITICALCVE-2026-47686

vm2 Sandbox Escape via Error.cause Host Object Leak (CVE-2026-47686)

Critical vm2 sandbox escape allows Node.js sandbox code to access the host process object via unsanitized Error.cause, enabling full RCE.

Dylan H.

Security Team

August 18, 2026
4 min read
vm2 Sandbox Escape via Error.cause Host Object Leak (CVE-2026-47686)

Critical severity

Rated critical. Prioritise patching — see the remediation guidance below.

Affected Products

  • vm2 < 3.11.6
  • Node.js applications using vm2 for sandboxing

Overview

A critical sandbox escape vulnerability (CVE-2026-47686) has been disclosed in vm2, the widely-used open-source JavaScript sandbox for Node.js. The flaw resides in lib/setup-sandbox.js where the handleException() function correctly sanitizes SuppressedError.error, SuppressedError.suppressed, and AggregateError.errors, but fails to sanitize Error.cause. This oversight allows sandbox-contained code to reach a powerful host-side object — such as process — and break out of the sandbox entirely.

The vulnerability carries a CVSS score of 9.9 (Critical) and was disclosed on August 17, 2026.


Vulnerability Details

FieldValue
CVE IDCVE-2026-47686
Componentvm2 (lib/setup-sandbox.js)
Vulnerability TypeSandbox Escape
CVSS Score9.9 (Critical)
Attack VectorNetwork
Privileges RequiredNone
User InteractionNone
Fixed Invm2 3.11.6

Technical Analysis

Root Cause

The handleException() function in lib/setup-sandbox.js is responsible for sanitizing error objects before they propagate from inside the sandbox to the host environment. The function strips dangerous properties from several error types:

  • SuppressedError.error — sanitized
  • SuppressedError.suppressed — sanitized
  • AggregateError.errors — sanitized
  • Error.cause — NOT sanitized (the vulnerability)

Since Error.cause was added to the JavaScript language specification as a standard chaining mechanism, any Error (or derived class) can carry a .cause property pointing to another object. The sanitization logic didn't account for this property, leaving a path for sandbox code to carry a host-realm object out through error propagation.

Attack Flow

  1. Sandbox code deliberately constructs or intercepts an error that carries a host-realm object (such as process) as its .cause value.
  2. The error escapes the sandboxed context via handleException().
  3. handleException() strips expected dangerous properties but passes .cause through untouched.
  4. The caller (in the host context) now holds a reference to the process object obtained from within the sandbox.
  5. The attacker leverages process access to execute arbitrary system commands, read environment variables, or exfiltrate data.

Impact

Full sandbox escape with access to the Node.js process object grants:

  • Arbitrary command execution — process.binding('spawn_sync') or similar internals
  • Environment variable access — secrets, credentials, API keys
  • File system access — read/write any file accessible to the Node.js process
  • Network access — establish outbound connections, exfiltrate data

Affected Versions

All versions of vm2 prior to 3.11.6 are vulnerable.


Remediation

Immediate Fix

Update vm2 to version 3.11.6 or later:

npm install vm2@latest
# or
yarn add vm2@latest

Verification

Confirm the installed version:

node -e "const {version} = require('vm2/package.json'); console.log(version);"

Expected output: 3.11.6 or higher.

If Immediate Update is Not Possible

  • Disable vm2 usage on any publicly accessible surface until patched.
  • Sandbox at the OS level using Docker containers, seccomp profiles, or gVisor rather than relying solely on vm2.
  • Audit all error propagation paths in code that calls vm2-sandboxed functions.

Detection

Check for Suspicious Error Objects

Monitor for errors carrying .cause values referencing host-side objects:

// Defensive wrapper — log if .cause escapes sandbox
const { VM } = require('vm2');
const vm = new VM({
  sandbox: {},
  eval: false,
  wasm: false,
});
 
try {
  vm.run(untrustedCode);
} catch (err) {
  if (err.cause && typeof err.cause === 'object') {
    console.warn('Potential sandbox escape attempt via Error.cause:', err.cause);
  }
  throw err;
}

SIEM / Log Queries

Look for unexpected process.exit() or child_process.exec() calls originating from Node.js processes hosting vm2:

index=app_logs sourcetype=nodejs
| search message="child_process" OR message="process.binding"
| where host_process="*vm2*"

Recommendations

  • Update vm2 to 3.11.6+ — highest priority action
  • Audit all vm2 call sites in your codebase for error propagation patterns
  • Add OS-level sandboxing (Docker, seccomp) as defence-in-depth
  • Review error handling — never blindly pass caught errors from sandboxed code into production logic
  • Pin vm2 version in package.json and enforce via lock file

Timeline

DateEvent
2026-08-17CVE-2026-47686 published to NVD
2026-08-17vm2 3.11.6 released with patch
2026-08-18Public advisory issued

Sources