Every CVE Search/ Get API key

CVE-2026-92950

vm2 before 3.11.7 Sandbox Escape via CLI require

9.3 CriticalFix available

vm2 before 3.11.7 contains a sandbox escape vulnerability in the CLI tool that allows attackers to execute arbitrary code in the host Node.js process. Attackers can supply a malicious script file to the vm2 CLI that uses require(__filename) to re-execute itself in the host realm, bypassing sandbox isolation and accessing host modules like fs and child_process.

Attack profile

How easy it is to exploit

Attack vector
Local
Complexity
Low
Privileges needed
None
User interaction
Passive

What an attacker can affect

Confidentiality
High
Integrity
High
Availability
High

Exploit likelihood

0.20%Unchanged since Sep 18, 2026
90%50%10%1%

What each source reports

CVE List Score used 9.3

vm2 before 3.11.7 Sandbox Escape via CLI require

vm2 before 3.11.7 contains a sandbox escape vulnerability in the CLI tool that allows attackers to execute arbitrary code in the host Node.js process. Attackers can supply a malicious script file to the vm2 CLI that uses require(__filename) to re-execute itself in the host realm, bypassing sandbox isolation and accessing host modules like fs and child_process.

Record
CVE-2026-92950
CVSS 4.0
9.3 CriticalCVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H
CVSS 3.1
8.6 HighCVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H
Weakness
CWE-453
Updated
2026-11-02
EUVDEUVD-2026-81599 9.3

vm2 before 3.11.7 contains a sandbox escape vulnerability in the CLI tool that allows attackers to execute arbitrary code in the host Node.js process. Attackers can supply a malicious script file to the vm2 CLI that uses require(__filename) to re-execute itself in the host realm, bypassing sandbox isolation and accessing host modules like fs and child_process.

Record
EUVD-2026-81599
CVSS 4.0
9.3 CriticalCVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H
Updated
2026-11-02
GitHub AdvisoriesGHSA-hc6q-4vvg-jf79 9.3

Duplicate Advisory: vm2 CLI provides no sandbox isolation - host-realm require() is reachable from sandboxed scripts

Duplicate Advisory

This advisory has been withdrawn because it is a duplicate of GHSA-jxxv-8r27-vm4p. This link is maintained to preserve external references.

Original Description

vm2 before 3.11.7 contains a sandbox escape vulnerability in the CLI tool that allows attackers to execute arbitrary code in the host Node.js process. Attackers can supply a malicious script file to the vm2 CLI that uses require(__filename) to re-execute itself in the host realm, bypassing sandbox isolation and accessing host modules like fs and child_process.

Record
GHSA-hc6q-4vvg-jf79
CVSS 4.0
9.3 CriticalCVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
CVSS 3.1
8.6 HighCVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H
Weakness
CWE-453
Updated
2026-11-02
GitHub AdvisoriesGHSA-jxxv-8r27-vm4p 8.6

vm2 CLI provides no sandbox isolation - host-realm require() is reachable from sandboxed scripts

Summary

The vm2 command-line tool installed by npm install -g vm2 and documented in the README's "CLI" section runs the supplied script under NodeVM with require:{external:true} and no root / context / builtin configured. With these defaults the resolver loads every relative or absolute require() target through the host require() function, executing the attacker's module body in the host Node.js process before the result is ever proxied back into the sandbox. A single attacker-controlled file passed to vm2 ./script.js can call require(__filename) to re-execute itself in host realm and reach fs, child_process, etc. The documented sandbox runner is therefore equivalent to node ./script.js. No additional files, flags, or user interaction are required.

Details

The vulnerability lets a malicious sandboxed script - the file argument to the documented vm2 <file> CLI - execute arbitrary code in the host Node.js process, crossing the sandbox → host boundary that vm2 is meant to enforce.

Vulnerable code path

  1. Source - bin/vm2:3 → lib/cli.js:7-18. process.argv[2] is the attacker-authored script path. The CLI invokes:
    NodeVM.file(path, { verbose: true, require: { external: true } });
    
    Without require.root, require.context, nor require.builtin.
  2. Hop - lib/nodevm.js:618-636. NodeVM.file reads the file and calls new NodeVM(options).run(body, resolvedFilename).
  3. Hop - lib/nodevm.js:335 → lib/resolver-compat.js:205-266 (makeResolverFromLegacyOptions). Destructures external:true, rootPaths=undefined, hostRequire=defaultRequire (line 218), context='host' (default, line 219). Because typeof externalOpt !== 'object' (line 265) it returns a CustomResolver with checkedRootPaths=undefined and pathContext = () => 'host' (line 263).
  4. Hop - lib/setup-node-sandbox.js:86-123 (requireImpl). Sandbox require(id) resolves via resolver.resolve(...) (lib/nodevm.js:380-383). lib/resolver.js:244-275 handles absolute/relative specifiers; tryFile at lib/resolver.js:327-329 gates on this.isPathAllowed(x).
  5. Barrier (gap) - lib/resolver-compat.js:53-54:
    isPathAllowed(filename) {
        if (this.rootPaths === undefined) return true;
    
    With no root configured, every filesystem path is allowed. checkAccess (lib/resolver.js:39-42) delegates to the same method.
  6. Sink - lib/resolver-compat.js:74-77:
    loadJS(vm, mod, filename) {
        if (this.pathContext(filename, 'js') !== 'host') return super.loadJS(...);
        const m = this.hostRequire(filename);   // ← host-realm require()
        mod.exports = vm.readonly(m);
    }
    
    hostRequire is defaultRequire (lib/resolver-compat.js:20-23) - the real host require(). The required module's top-level body executes in the host realm before vm.readonly() wraps the exports; wrapping happens too late to constrain side-effects. loadNode (lib/resolver-compat.js:80-83) is identical for .node native addons (process.dlopen in host).

PoC

Save the following as /tmp/poc.js:

'use strict';
try {
    // Host realm: fs is available - write sentinel and stop.
    const fs = require('fs');
    fs.writeFileSync('/tmp/vm2.proof', 'host pid=' + process.pid + '\n');
    console.log('HOST realm: wrote /tmp/vm2.proof');
} catch (e) {
    // Sandbox realm: require('fs') threw ENOTFOUND. Re-require this file -
    // the CLI resolver loads it via host require() (resolver-compat.js:76).
    console.log('sandbox realm: fs blocked (' + e.message + '); escaping');
    require(__filename);
}

Run via the shipped CLI exactly as the README documents:

node ./bin/vm2 /tmp/poc.js        # or `vm2 /tmp/poc.js` after `npm i -g vm2`

Observed output:

sandbox realm: fs blocked (Cannot find module 'fs'); escaping
HOST realm: wrote…
Record
GHSA-jxxv-8r27-vm4p
CVSS 3.1
8.6 HighCVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H
Weakness
CWE-453, CWE-829, CWE-1188
Updated
2026-11-02
NVD 9.3

vm2 before 3.11.7 contains a sandbox escape vulnerability in the CLI tool that allows attackers to execute arbitrary code in the host Node.js process. Attackers can supply a malicious script file to the vm2 CLI that uses require(__filename) to re-execute itself in the host realm, bypassing sandbox isolation and accessing host modules like fs and child_process.

Record
CVE-2026-92950
CVSS 4.0
9.3 CriticalCVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
CVSS 3.1
8.6 HighCVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H
Weakness
CWE-453
Updated
2026-11-02
OSV 9.3

vm2 before 3.11.7 Sandbox Escape via CLI require

vm2 before 3.11.7 contains a sandbox escape vulnerability in the CLI tool that allows attackers to execute arbitrary code in the host Node.js process. Attackers can supply a malicious script file to the vm2 CLI that uses require(__filename) to re-execute itself in the host realm, bypassing sandbox isolation and accessing host modules like fs and child_process.

Record
CVE-2026-92950
CVSS 4.0
9.3 CriticalCVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H
Weakness
CWE-453
Updated
2026-11-02
Show 5 moreShow less
OSVGHSA-hc6q-4vvg-jf79 9.3

Duplicate Advisory: vm2 CLI provides no sandbox isolation - host-realm require() is reachable from sandboxed scripts

Duplicate Advisory

This advisory has been withdrawn because it is a duplicate of GHSA-jxxv-8r27-vm4p. This link is maintained to preserve external references.

Original Description

vm2 before 3.11.7 contains a sandbox escape vulnerability in the CLI tool that allows attackers to execute arbitrary code in the host Node.js process. Attackers can supply a malicious script file to the vm2 CLI that uses require(__filename) to re-execute itself in the host realm, bypassing sandbox isolation and accessing host modules like fs and child_process.

Record
GHSA-hc6q-4vvg-jf79
CVSS 4.0
9.3 CriticalCVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
CVSS 3.1
8.6 HighCVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H
Weakness
CWE-453
Updated
2026-11-02
OSVGHSA-jxxv-8r27-vm4p 8.6

vm2 CLI provides no sandbox isolation - host-realm require() is reachable from sandboxed scripts

Summary

The vm2 command-line tool installed by npm install -g vm2 and documented in the README's "CLI" section runs the supplied script under NodeVM with require:{external:true} and no root / context / builtin configured. With these defaults the resolver loads every relative or absolute require() target through the host require() function, executing the attacker's module body in the host Node.js process before the result is ever proxied back into the sandbox. A single attacker-controlled file passed to vm2 ./script.js can call require(__filename) to re-execute itself in host realm and reach fs, child_process, etc. The documented sandbox runner is therefore equivalent to node ./script.js. No additional files, flags, or user interaction are required.

Details

The vulnerability lets a malicious sandboxed script - the file argument to the documented vm2 <file> CLI - execute arbitrary code in the host Node.js process, crossing the sandbox → host boundary that vm2 is meant to enforce.

Vulnerable code path

  1. Source - bin/vm2:3 → lib/cli.js:7-18. process.argv[2] is the attacker-authored script path. The CLI invokes:
    NodeVM.file(path, { verbose: true, require: { external: true } });
    
    Without require.root, require.context, nor require.builtin.
  2. Hop - lib/nodevm.js:618-636. NodeVM.file reads the file and calls new NodeVM(options).run(body, resolvedFilename).
  3. Hop - lib/nodevm.js:335 → lib/resolver-compat.js:205-266 (makeResolverFromLegacyOptions). Destructures external:true, rootPaths=undefined, hostRequire=defaultRequire (line 218), context='host' (default, line 219). Because typeof externalOpt !== 'object' (line 265) it returns a CustomResolver with checkedRootPaths=undefined and pathContext = () => 'host' (line 263).
  4. Hop - lib/setup-node-sandbox.js:86-123 (requireImpl). Sandbox require(id) resolves via resolver.resolve(...) (lib/nodevm.js:380-383). lib/resolver.js:244-275 handles absolute/relative specifiers; tryFile at lib/resolver.js:327-329 gates on this.isPathAllowed(x).
  5. Barrier (gap) - lib/resolver-compat.js:53-54:
    isPathAllowed(filename) {
        if (this.rootPaths === undefined) return true;
    
    With no root configured, every filesystem path is allowed. checkAccess (lib/resolver.js:39-42) delegates to the same method.
  6. Sink - lib/resolver-compat.js:74-77:
    loadJS(vm, mod, filename) {
        if (this.pathContext(filename, 'js') !== 'host') return super.loadJS(...);
        const m = this.hostRequire(filename);   // ← host-realm require()
        mod.exports = vm.readonly(m);
    }
    
    hostRequire is defaultRequire (lib/resolver-compat.js:20-23) - the real host require(). The required module's top-level body executes in the host realm before vm.readonly() wraps the exports; wrapping happens too late to constrain side-effects. loadNode (lib/resolver-compat.js:80-83) is identical for .node native addons (process.dlopen in host).

PoC

Save the following as /tmp/poc.js:

'use strict';
try {
    // Host realm: fs is available - write sentinel and stop.
    const fs = require('fs');
    fs.writeFileSync('/tmp/vm2.proof', 'host pid=' + process.pid + '\n');
    console.log('HOST realm: wrote /tmp/vm2.proof');
} catch (e) {
    // Sandbox realm: require('fs') threw ENOTFOUND. Re-require this file -
    // the CLI resolver loads it via host require() (resolver-compat.js:76).
    console.log('sandbox realm: fs blocked (' + e.message + '); escaping');
    require(__filename);
}

Run via the shipped CLI exactly as the README documents:

node ./bin/vm2 /tmp/poc.js        # or `vm2 /tmp/poc.js` after `npm i -g vm2`

Observed output:

sandbox realm: fs blocked (Cannot find module 'fs'); escaping
HOST realm: wrote…
Record
GHSA-jxxv-8r27-vm4p
CVSS 3.1
8.6 HighCVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H
Weakness
CWE-1188, CWE-453, CWE-829
Updated
2026-11-02
OSVCLSA-2026-1790888247 No score

TuxCare security update for vm2 (15 CVEs)

TuxCare rebuilt vm2 to address 15 CVEs. Fixed in 3.11.5-tuxcare.3.

Record
CLSA-2026-1790888247
Updated
2026-11-02
OSVCLSA-2026-1790937673 No score

TuxCare security update for vm2 (7 CVEs)

TuxCare rebuilt vm2 to address 7 CVEs. Fixed in 3.10.0-tuxcare.2.

Record
CLSA-2026-1790937673
Updated
2026-11-02
OSVROOT-APP-NPM-CVE-2026-92950 No score

CVE-2026-92950 in vm2 - Patched by Root

Root has patched CVE-2026-92950 in the vm2 package for Root:npm. Multiple fixed versions available.

Record
ROOT-APP-NPM-CVE-2026-92950
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
vm2
npm
through 3.11.6
3.11.7
vm2
TuxCare:npm
From an advisory covering 13 CVEs
3.11.5-tuxcare.0 up to 3.11.5-tuxcare.3, plus listed versions
3.11.53.11.5-tuxcare.13.11.5-tuxcare.2
3.11.5-tuxcare.3
vm2
TuxCare:npm
From an advisory covering 6 CVEs
3.10.0-tuxcare.0 up to 3.10.0-tuxcare.2, plus listed versions
3.10.03.10.0-tuxcare.1
3.10.0-tuxcare.2
vm2
npm
before 3.11.7
3.11.7
vm2
Root:npm
before 3.10.5-aikido.8
3.10.5-aikido.83.11.6-aikido.1
@rootio/vm2
Root:npm
before 3.10.5-root.io.8
3.10.5-root.io.83.11.6-root.io.1

History

History
RecordedChangedSources
affected, facts
affected
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-92950 is a critical vulnerability (CVSS 9.3) in Patriksimek Vm2, published September 17, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.20%, the 9th percentile. Fixed in vm2 3.11.7.

References

This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open