vm2 NodeVM `nesting: true` bypasses `require: false` allowing sandbox escape and arbitrary OS command execution
Date: 2026-05
Affected: npm/vm2
Attack vector: command-injection
Category: vulnerability-disclosure
Severity: Critical
CVE: CVE-2026-44007
CWE: CWE-284
CWE-693
CVSS: 9.1 (CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H)

### Summary When a `NodeVM` is created with `nesting: true`, sandbox code can unconditionally `require('vm2')` regardless of the outer VM's `require` configuration — including `require: false`. With access to `vm2`, the sandbox constructs a new inner `NodeVM` with its own unrestricted `require` settings and executes arbitrary OS commands on the host. Any application that runs untrusted code inside a `NodeVM` with `nesting: true` is fully compromised. ### Details The vulnerability is in how the `nesting: true` option interacts with the legacy module resolver. **`lib/nodevm.js:96-99`** — `NESTING_OVERRIDE` is a special builtin map that injects the `vm2` package into the sandbox: ```js const NESTING_OVERRIDE = Object.freeze({ __proto__: null, vm2: vm2NestingLoader }); ``` **`lib/nodevm.js:268-269`** — When `nesting: true`, this override is passed into the resolver factory alongside the host's `require` options: ```js const customResolver = requireOpts instanceof Resolver; const resolver = customResolver ? requireOpts : makeResolverFromLegacyOptions( requireOpts, nesting && NESTING_OVERRIDE, // ← injected when nesting:true this._compiler ); ``` **`lib/resolver-compat.js:193-197`** — This is the vulnerable branch. When `require: false` is set, `requireOpts` is falsy, so `!options` is true. Without nesting the function returns `DENY_RESOLVER` (block everything). With nesting, it instead builds a resolver that includes `vm2` from `NESTING_OVERRIDE`: ```js functio


Mitigations:

Architectural layers (MAESTRO):