Medium · 5.4 Node.js & npm GHSA-6w8r-xxw2-g3hx CVE-2026-92938 GHSA-8686-vhfx-7r3j CVE-2026-92957
Six vm2 Sandbox Escape Vulnerabilities Allow Arbitrary Code Execution on the Host
Six vulnerabilities in the vm2 JavaScript sandboxing library, several rated critical (CVSS 9.4), let sandboxed code escape NodeVM isolation and reach host builtins such as node:sqlite, child_process, and fs/promises, enabling native code execution, command execution, and filesystem writes on the host. All issues are fixed in vm2 3.11.7.
- GitHub Advisory Database database 1w ago · view ↗
- NVD (NIST) database 3w ago · view ↗
- GitHub Advisory Database database 1w ago · view ↗
- NVD (NIST) database 2w ago · view ↗
- GitHub Advisory Database database 1w ago · view ↗
- NVD (NIST) database 3w ago · view ↗
- GitHub Advisory Database database 1w ago · view ↗
- NVD (NIST) database 3w ago · view ↗
- GitHub Advisory Database database 1w ago · view ↗
- NVD (NIST) database 2w ago · view ↗
- GitHub Advisory Database database 1w ago · view ↗
- NVD (NIST) database 3w ago · view ↗
AI summary
Six distinct vulnerabilities have been disclosed in vm2, a Node.js library used to run untrusted JavaScript inside a sandboxed VM (NodeVM). All six stem from gaps in how vm2 restricts sandboxed code's access to Node.js builtin modules and object protections such as freeze/readonly. Three of the issues carry a CVSS score of 9.4 and allow sandboxed code to fully escape isolation, reaching native code execution or host command execution. A fourth, scored 8.4, allows host filesystem writes. The remaining two are lower severity (6.3 and 2.3) and involve weaker bypasses of object immutability and module allowlisting. All six are fixed in vm2 3.11.7.
What Happened
Security researchers identified six separate ways that code running inside vm2's NodeVM sandbox could break out of its intended isolation. The flaws share a common root cause: vm2's builtin-module allowlist/denylist logic and its object-freezing protections rely on string-matching and prefix logic that can be circumvented. Three of the six issues (CVE-2026-92938, CVE-2026-92957, CVE-2026-92948) permit sandboxed code to reach host-level Node.js builtins that should have been blocked, resulting in native code execution or command execution on the host process. A fourth (CVE-2026-92958) allows sandboxed code to reach the fs/promises filesystem API despite fs being explicitly denied, enabling file writes on the host. A fifth (CVE-2026-92949) allows sandboxed code to bypass vm.freeze()/vm.readonly() object protections by invoking host object setters directly. A sixth (CVE-2026-92945) allows sandboxed code to load non-allowlisted packages that share a name prefix with an allowlisted module.
Technical Cause
CVE-2026-92938: vm2 wraps the node:sqlite builtin with vm.readonly(), which blocks property assignment but leaves callable methods reachable. Because vm2's resolver strips only a single 'node:' prefix, a sandbox request for 'node:node:sqlite' resolves to the configured node:sqlite entry, letting sandboxed code create a DatabaseSync instance and call loadExtension() to load a native library into the host process, achieving arbitrary native code execution with host-process privileges. CVE-2026-92957: NodeVM's wildcard require policy supports negative (deny) entries, but these are matched by exact string comparison against canonical builtin names rather than being normalized for the 'node:' prefix. A policy like builtin: ['*', '-node:child_process'] therefore fails to deny the canonical 'child_process' name, so sandboxed code can still require('child_process') and obtain process-spawning APis such as execSync and spawn. CVE-2026-92948: On Node.js 24+, module.builtinModules exposes a scheme-only key 'node:test' that is not covered by vm2's family-based DANGEROUS_BUILTINS protection. Because the resolver strips only one 'node:' prefix, a request for 'node:node:test' resolves to the stored node:test entry. Calling node:test.run() forwards attacker-controlled execArgv values (such as --eval=<JavaScript>) to a separate host Node process, resulting in arbitrary JavaScript execution outside the sandbox. CVE-2026-92958: Negative builtin denylist entries (e.g. '-fs') are matched by exact module name only, so they do not cover subpaths such as fs/promises. Sandboxed code can therefore require('fs/promises') or require('node:fs/promises') and reach filesystem write/read operations despite fs being denied. CVE-2026-92949: vm2's object-freezing protections (vm.freeze(), vm.readonly()) do not properly restrict access to accessor properties. Sandboxed code can use Object.getOwnPropertyDescriptor() or __lookupSetter__() to extract and directly invoke host object setters, mutating properties intended to be read-only. CVE-2026-92945: The isPathAllowedForModule allowlist check uses raw string prefix matching instead of boundary-anchored comparison, so a module name that shares a prefix with an allowlisted module can be reached via relative requires from an allowlisted package, even when transitive loading is disabled.
Why It Matters
vm2 is designed specifically to run untrusted JavaScript safely, so any sandbox escape undermines its core purpose. The three critical-rated flaws (CVSS 9.4) let untrusted plugin or script code obtain full native code execution or host command execution, equivalent to running arbitrary code with the privileges of the host Node.js process. The filesystem-access flaw (CVSS 8.4) allows unauthorized reads and writes outside the sandbox. Applications that embed vm2 to execute third-party plugins, user scripts, or other untrusted code are directly exposed to full host compromise if any of these builtins are permitted in their configuration.
Who Is Affected
Any application using vm2's NodeVM to sandbox untrusted JavaScript is potentially affected, depending on which builtin modules are permitted in the embedder's configuration. CVE-2026-92938 requires node:sqlite to be permitted (explicitly or via builtin: ['*']). CVE-2026-92957 and CVE-2026-92958 affect configurations using wildcard require policies with negative (deny) entries intended to block specific builtins. CVE-2026-92948 requires node:test to be explicitly permitted and affects Node.js 24 and newer. CVE-2026-92949 and CVE-2026-92945 affect vm.freeze()/vm.readonly() usage and external module allowlisting, respectively, regardless of specific builtin configuration.
Affected Versions
CVE-2026-92938 affects vm2 versions 3.11.3 through 3.11.6. CVE-2026-92957 and CVE-2026-92958 affect vm2 versions up to and including 3.11.6. CVE-2026-92948 and CVE-2026-92949 affect vm2 versions 3.9.6 through 3.11.6. CVE-2026-92945 affects vm2 versions up to and including 3.11.6. All six issues are fixed in vm2 3.11.7.
Fixes and Mitigation
All six vulnerabilities are fixed in vm2 3.11.7. No partial mitigations or workarounds beyond upgrading are described in the available facts.
Recommended Action
Upgrade vm2 to version 3.11.7 as soon as possible. Until upgraded, review your NodeVM configuration: avoid permitting node:sqlite or node:test builtins, avoid relying on negative (deny) entries in wildcard require policies to block child_process or fs (since these can be bypassed), and treat vm.freeze()/vm.readonly() as insufficient on their own to prevent property mutation. Audit any external module allowlists for prefix-matching weaknesses.
PatchBriefing score
5.4 / 10 · Medium
Official CVSS: 9.4
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/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
Why this score
Three vulnerabilities (CVE-2026-92938, CVE-2026-92957, CVE-2026-92948) carry a CVSS score of 9.4, reflecting that they allow full sandbox escape resulting in native code execution or host command execution with no privileges beyond low-level sandbox access and no user interaction required. A fourth (CVE-2026-92958) scores 8.4, reflecting host filesystem write access rather than full code execution. The remaining two score lower: CVE-2026-92949 at 6.3 (a localized object-immutability bypass) and CVE-2026-92945 at 2.3 (a narrow module allowlist bypass requiring specific prefix-sharing conditions and partial privileges). The PatchWire scores (4.3–5.4 for most, 1.5 for the lowest) reflect that a fix is available for all issues and that no known exploitation or public exploit code currently exists.
Affected versions
- vm2 >= 3.11.3, <= 3.11.6
- vulnerable
- ≥ 3.11.7
- patched
- vm2 <= 3.11.6
- vulnerable
- ≥ 3.11.7
- patched
- vm2 >= 3.9.6, <= 3.11.6
- vulnerable
- ≥ 3.11.7
- patched
- vm2 <= 3.11.6
- vulnerable
- ≥ 3.11.7
- patched
- vm2 >= 3.9.6, <= 3.11.6
- vulnerable
- ≥ 3.11.7
- patched
- vm2 <= 3.11.6
- vulnerable
- ≥ 3.11.7
- patched
Reported fixes
All six vulnerabilities are fixed in vm2 3.11.7. No partial mitigations or workarounds beyond upgrading are described in the available facts.
How this was built
12 source records were collected, matched and used to prepare the report above.
-
GitHub Advisory Database database
-
NVD (NIST) database
-
GitHub Advisory Database database
-
NVD (NIST) database
-
GitHub Advisory Database database
-
NVD (NIST) database
Revision history
- Published
- Generated
Related
Relevant changes for the stacks you follow.
Choose your stacks, topics and optional WordPress plugins. At 07:00 CEST, matching advisories and releases from the reporting period are grouped into one email.
✓ Choose stacks and topics✓ Change preferences anytime✓ One grouped email