Severity by source
Sources disagree (Medium–Critical)AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
vuln.today treats the vendor’s rating as authoritative. A higher third-party CVSS (e.g. CISA-ADP) is shown for transparency but does not drive the headline severity.
CVSS VectorVendor: https://github.com/patriksimek/vm2
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
Lifecycle Timeline
3Blast Radius
ecosystem impact- 88 npm packages depend on vm2 (4 direct, 84 indirect)
Ecosystem-wide dependent count for version 3.11.4.
DescriptionCVE.org
Summary
NodeVM blocks several dangerous Node.js builtins such as module, worker_threads, cluster, vm, repl, and inspector.
However, the denylist misses process and inspector/promises. Both can be used from sandboxed code to reach host-side execution primitives.
This allows sandboxed code to bypass the intended builtin restrictions and execute code in the host process.
Details
The dangerous builtin denylist is defined in lib/builtin.js. This list does not include:
process
inspector/promisesNon-denied builtins are exposed to the sandbox through:
builtins.set(key, special ? special : vm => vm.readonly(hostRequire(key)));Because of this, sandboxed code can bypass the expected restrictions in two ways:
require('process').getBuiltinModule('child_process')reloadschild_process, even whenchild_processis excluded.require('inspector/promises')exposes the Inspector protocol and can callRuntime.evaluatein the host process.
PoC
Tested on:
vm2: 3.11.2
Node.js: v25.9.0Run from the vm2 repository root:
node poc/dangerous-builtin-denylist-rce.jsdangerous-builtin-denylist-rce.js
The PoC first confirms the intended restrictions work:
require("inspector"): BLOCKED
require("child_process"): BLOCKEDThen it bypasses them:
require("process").getBuiltinModule("child_process").execFileSync(...)This spawns a host child process. It also confirms:
require("inspector/promises").Session().post("Runtime.evaluate", ...)This evaluates JavaScript in the host process.
<img width="858" height="766" alt="Screenshot 2026-05-10 at 11 53 33 AM" src="https://github.com/user-attachments/assets/7614aecb-5ffd-4c41-bfe8-e1fcb3b1bb59" />
Impact
An attacker who can run untrusted JavaScript inside NodeVM with affected builtin settings can escape the sandbox and execute arbitrary code in the host process.
This can lead to full compromise of the application process, including reading files, writing files, spawning processes, and accessing host environment secrets.
(This is not reachable with the default NodeVM configuration where require is disabled or no affected builtins are allowed. It affects applications that allow process, inspector/promises, or the wildcard "*" in require.builtin.)
Suggested fix
Add process and inspector/promises to the dangerous builtin blocklist.
Also consider blocking dangerous builtin families by prefix, for example blocking both:
inspector
inspector/*instead of only exact module names.
AnalysisAI
Sandbox escape leading to remote code execution in vm2 NodeVM versions 3.11.3 and earlier allows attackers running untrusted JavaScript inside the sandbox to break out via two missing entries in the dangerous-builtin denylist: process (whose getBuiltinModule() reloads any core module, including child_process) and inspector/promises (whose Session().post('Runtime.evaluate', ...) evaluates code in the host realm). The flaw is exploitable only when the embedder allows process, inspector/promises, or wildcard * in require.builtin. Publicly available exploit code exists (PoC published with the advisory), and a patch is available in vm2 3.11.4; no public exploit identified at time of analysis as actively used in the wild.
Technical ContextAI
vm2 is a widely used Node.js sandbox library (pkg:npm/vm2) that wraps the native vm module to run untrusted JavaScript with controlled access to Node builtins via an embedder-defined allowlist. The defensive denylist in lib/builtin.js historically used exact-match name comparison and explicitly blocked known-dangerous modules (module, worker_threads, cluster, vm, repl, inspector). The CWE-693 (Protection Mechanism Failure) root cause is two gaps in that denylist: the process module exposes getBuiltinModule(name) (Node 22+), which reloads any core module regardless of allow/deny configuration, and inspector/promises is a subpath sibling of the already-blocked inspector that was missed by the exact-name check. Both reach Node's Inspector and child-process primitives that run in the host realm, bypassing the sandbox boundary. The upstream fix in commit a1ed47a98d1cc36cb48c0d566d55889688e0b59b promotes the check to a family-prefix isDangerousBuiltin(key), strips node: URL spellings, and adds process to the dangerous set, codified as Defense Invariant #13.
RemediationAI
Vendor-released patch: vm2 3.11.4 - upgrade immediately via npm install vm2@3.11.4 or update lockfiles accordingly; the fix (commit a1ed47a) is a non-breaking patch release with no API changes for valid configurations. As an interim mitigation if upgrade is blocked, audit every NodeVM instantiation and remove process, inspector/promises, and wildcard * from require.builtin, restricting to an explicit minimal allowlist; this preserves the rest of the sandbox at the cost of losing any legitimate use of process inside guest code. If untrusted code is being run, consider disabling require entirely in the NodeVM options, which the vendor confirms is unaffected. Refer to the GitHub Security Advisory at https://github.com/patriksimek/vm2/security/advisories/GHSA-rp36-8xq3-r6c4 and the patch commit at https://github.com/patriksimek/vm2/commit/a1ed47a98d1cc36cb48c0d566d55889688e0b59b for verification.
FortiOS and FortiProxy contain an authentication bypass via the Node.js websocket module allowing unauthenticated remote
Eval injection vulnerability in the internals.batch function in lib/batch.js in the bassmaster plugin before 1.5.2 for t
Flowise version 3.0.5 contains a remote code execution vulnerability in the CustomMCP node. The mcpServerConfig paramete
Node.js 8.5.0 before 8.6.0 allows remote attackers to access unintended files, because a change to ".." handling was inc
An issue was discovered in the node-serialize package 0.0.4 for Node.js. Rated critical severity (CVSS 9.8), this vulner
Directory traversal vulnerability in the st module before 0.2.5 for Node.js allows remote attackers to read arbitrary fi
Multiple SQL injection vulnerabilities in the Manage Accounts page in the AccountManagement.asmx service in the Solarwin
The JS-YAML module before 2.0.5 for Node.js parses input without properly considering the unsafe !!js/function tag, whic
Directory traversal vulnerability in lib/app/index.js in Geddy before 13.0.8 for Node.js allows remote attackers to read
Credential-harvesting malware compromised 84 versions of 42 TanStack npm packages on 2026-05-11 via chained GitHub Actio
Eval injection vulnerability in index.js in the syntax-error package before 1.1.1 for Node.js 0.10.x, as used in IBM Rat
The HTTP server in Node.js 0.10.x before 0.10.21 and 0.8.x before 0.8.26 allows remote attackers to cause a denial of se
Same weakness CWE-693 – Protection Mechanism Failure
View allVendor StatusVendor
Share
External POC / Exploit Code
Leaving vuln.today
EUVD-2026-36446
GHSA-rp36-8xq3-r6c4