OFFLINE
Awaiting data
Security intelligence
CriticalCritical vulnerability

CVE-2026-92935: vm2: NodeVM nesting guard accepts array-shaped require and permits host RCE

GitHub Advisories · officialPublished Oct 1, 2026Risk 50/100

## Summary The `NodeVM` constructor computes `hasRealRequireConfig` using `typeof requireOpts === 'object' && requireOpts !== null`, so `require: []` bypasses the guard intended to reject `nesting` without an explicit require configuration. `makeResolverFromLegacyOptions()` then destructures the array to undefined option fields and returns a resolver containing only `NESTING_OVERRIDE.vm2`. Any attacker whose JavaScript is executed by a downstream `NodeVM` configured with `{nesting: true, require: []}` can load the host `vm2` module, create an inner `NodeVM` with an attacker-selected builtin allowlist, and execute commands as the host process. No equivalent plain-object validation exists in `makeResolverFromLegacyOptions()`. Array is converted into the vm2-only resolver: https://github.com/patriksimek/vm2/blob/54b54b74a382577f0bcd0538c5bf99acdcd7f53b/lib/resolver-compat.js#L205-L226 Nesting loader returns the host VM constructors: https://github.com/patriksimek/vm2/blob/54b54b74a382577f0bcd0538c5bf99acdcd7f53b/lib/nodevm.js#L640-L645 ## Proof of Concept Preconditions: - The host creates `NodeVM` with truthy `nesting` and array-shaped `require`. - The attacker can supply JavaScript executed by that `NodeVM`. ```javascript 'use strict'; const {NodeVM} = require('./index.js'); const outer = new NodeVM({nesting: true, require: []}); const result = outer.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()" ); `); console.log(result); ``` ```text uid=1000(lohar) gid=1000(lohar) groups=1000(lohar) ``` The `hasRealRequireConfig` guard fails open because it returns `true` for arrays, although arrays are not `VMRequire` configuration objects. `makeResolverFromLegacyOptions()` applies object destructuring to the array, obtains undefined `builtin` and `external` values, merges `NESTING_OVERRIDE`, and returns before any external-module control is relevant. Outer builtin restrictions do not constrain the attacker-created inner `NodeVM`, whose `require` configuration is selected inside the sandbox. Failed shape check: https://github.com/patriksimek/vm2/blob/54b54b74a382577f0bcd0538c5bf99acdcd7f53b/lib/nodevm.js#L304-L307 ## Impact An attacker can execute arbitrary commands with the host Node.js process privileges, including reading secrets, modifying files, and accessing the host network. GHSA-m4wx-m65x-ghrr covers the same nesting primitive but does not cover array-shaped `require` values and incorrectly identifies 3.11.4 as patched. > Exploitation is limited to downstream applications that enable `nesting` and pass the malformed array configuration.

Upgrade affected packages to a patched version: vm2 3.11.7.

Vendor
Not specified
Product
vm2
Exploitation
none known
Evidence
official
CVSS
9.0

This record is attributed to GitHub Advisories. Exploitation status and remediation guidance are kept separate from the vulnerability's technical severity.

Open primary source