vm2 NodeVM Sandbox Escape: child_process Omitted from Denylist Enables Host RCE (CVE-2026-93605)
What happened
A critical advisory (GHSA-pq68-rvw4-xp4r, CVE-2026-93605, CVSS 10.0) discloses a sandbox escape in a vm2 fork's NodeVM. The DANGEROUS_BUILTINS denylist in lib/builtin.js blocks a long list of host-reaching core modules — module, worker_threads, cluster, vm, repl, inspector, process, os, dns, v8, and others — even when a sandbox is configured with require:{builtin:['*']} or names a module explicitly. The list omits child_process. A script running inside the sandbox can call require('child_process').execSync(...) and execute arbitrary commands with the host process's privileges. A public PoC is available, and the report notes this is internally inconsistent with the project's own stated invariant that such primitives must never be reachable, even on explicit request.
Why it matters
This affects any deployment that runs untrusted or third-party JavaScript inside this vm2 fork's NodeVM using builtin:['*'] (or the documented ['*','-x',...] subtract pattern), or that explicitly allowlists child_process on the assumption the denylist would catch it the way it catches cluster or worker_threads. Per the advisory, the attacker only needs to control the sandboxed script — a single require('child_process') call — and the result is full host command execution, not a partial or limited escape. Any plugin system, code-execution-as-a-service, CI job runner, or multi-tenant platform built on affected NodeVM configurations should treat this as a complete sandbox bypass.
What defenders should do now
- Inventory any use of vm2/NodeVM (including forks) and check the exact version and
require.builtinconfiguration in use; the advisory states this affects versions before 3.12.1. - Review sandbox configs for
builtin:['*'], subtract-pattern allowlists, or explicitchild_processentries — these are the exploitable configurations described in the advisory. - As a stopgap, restrict sandboxes to an explicit minimal allowlist that excludes
child_process, and avoid the'*'wildcard entirely until patched. - Hunt for anomalous child-process spawns (e.g., shell invocations,
id,whoami, reverse shells) originating from Node.js processes that host sandboxed/plugin execution, especially where the parent process is not expected to spawn subprocesses. - Treat any sandboxed code execution as equivalent to host code execution until the fix is confirmed deployed — do not rely on the denylist as a security boundary against untrusted input in the interim.
Developing intel
This is a same-day disclosure; full patch adoption and downstream impact across projects embedding this vm2 fork are still unfolding. Details here reflect the GHSA advisory as published and may be updated as more information emerges. Source: GHSA-pq68-rvw4-xp4r.