Security Digest · Aug 17, 2026 · Vulnerability · Library
vm2: 22 Critical Sandbox Escapes, Fixed in 3.12.2
35 vm2 advisories (Aug 17-Oct 7, 2026), 22 critical, show sandbox escapes to host RCE, some from a default new VM(). Upgrade to 3.12.2; isolate untrusted code.
Our verdict
Check exposure
If anything outside your trust boundary can get code into vm2, upgrade to 3.12.2 today and plan to move that code out of process; if vm2 only runs your own code, upgrade on a normal cycle.
Who must act: Apps that use vm2 to run user-, tenant- or model-supplied JavaScript (plugin systems, rule and template engines, workflow and low-code tools, online code runners, AI agent code tools), directly or through a dependency.
Who can relax: Projects where vm2 is a transitive dependency that never evaluates attacker-influenced code; patch it, but no escape is reachable without control of the sandboxed script.
- Affected
- vm2 3.12.1 and earlier (each advisory lists its own range; the newest fixes need 3.12.2)
- Fixed in
- vm2 3.12.2 (released Sep 8, 2026; latest on npm as of Oct 21, 2026)
- CVSS
- 10.0 (v3.1, CNA)
- EPSS
- 1.0% (percentile 63)
- CISA KEV
- Not listed
- Exploitation
- Public proof-of-concept
- Severity
- Critical
- CVE
- CVE-2026-47683 CVE-2026-47686 CVE-2026-47698 CVE-2026-92945 CVE-2026-92941 CVE-2026-92944 CVE-2026-92939 CVE-2026-92938 CVE-2026-92937 CVE-2026-92935 CVE-2026-92949 CVE-2026-92957 CVE-2026-92958 CVE-2026-92951 CVE-2026-92940 CVE-2026-92950 CVE-2026-92948 CVE-2026-92952 CVE-2026-92956 CVE-2026-92947 CVE-2026-92946 CVE-2026-92942 CVE-2026-92936 CVE-2026-92933 CVE-2026-92934 CVE-2026-92953 CVE-2026-92954 CVE-2026-92955 CVE-2026-92959 CVE-2026-100723 CVE-2026-100722 CVE-2026-100721 CVE-2026-93605
- GHSA
- GHSA-gmc2-2x9w-cgh9 GHSA-m283-3h24-438v GHSA-cfcw-xp6x-25gj GHSA-m5w8-4gq2-6f8x GHSA-v836-6xw4-9cx3 GHSA-7q3f-wx44-378m GHSA-98xx-8mx4-x7cm GHSA-27g9-p43v-cw3v GHSA-46pr-c5wc-xffx GHSA-6w8r-xxw2-g3hx GHSA-647f-g98j-qq25 GHSA-8hr7-r645-pc6w GHSA-633r-hq9m-c4ff GHSA-8686-vhfx-7r3j GHSA-6rh5-qq4q-97xh GHSA-c48m-32m9-vx93 GHSA-h85j-hv3c-qfgq GHSA-jxxv-8r27-vm4p GHSA-qhwx-74w5-xhxq GHSA-jf8q-945g-9q4c GHSA-wjwh-qqvp-g4p4 GHSA-fcqc-726x-5wfc GHSA-j3hm-6rg5-mchv GHSA-r4fx-v8hh-22mv GHSA-x6m4-chr9-cg97 GHSA-r273-hxvj-fxhp GHSA-x965-fc75-jpqh GHSA-3vgf-8m4q-q4qr GHSA-gjq8-xm47-88rc GHSA-88hf-g992-jg85 GHSA-f8gf-w286-fmq2 GHSA-489w-w794-jq94 GHSA-2v2p-6j97-cjg9 GHSA-5h3f-q97h-ccvc GHSA-pq68-rvw4-xp4r
What to do
- Find every copy: run npm ls vm2 --all (or pnpm why vm2 / yarn why vm2) in each service and image.
- Upgrade to vm2 3.12.2, forcing transitive copies with an npm overrides (or pnpm/yarn resolutions) entry, then rebuild and redeploy.
- If the sandbox runs code from outside your trust boundary, move it to stronger isolation: a separate low-privilege process or Worker, a container, gVisor or Firecracker, as the vm2 README recommends.
- Until then, avoid NodeVM builtin: ['*'], nesting: true and require.external without require.root, and do not expose host functions that throw or return host objects.
- If untrusted code ran under an older vm2, rotate the secrets that Node process could read: environment variables, cloud and database credentials, tokens.
How to check if you are affected or compromised
- Check versions in lockfiles: grep -n '"node_modules/vm2"' -A2 package-lock.json, or npm ls vm2 --all.
- Review stored or logged sandbox submissions for escape primitives named in the advisories: child_process, Error.cause tricks, __lookupGetter__, Symbol.species, WebAssembly.compileStreaming, crypto setEngine, node:sqlite, node:test.
- On hosts that ran untrusted code, look for child processes of node (sh, curl, id), unexpected outbound connections and new files written by the app user.
What happened#
Between August 17 and October 7, 2026, the GitHub Advisory Database published 35 reviewed advisories for vm2, the npm library that runs JavaScript in a sandbox inside your own Node.js process. 22 are rated critical, most with CVSS 3.1 scores from 9.8 to 10.0, and most of those are escapes from the sandbox to code execution on the host. The fixes shipped first: per the npm registry, vm2 3.11.6 came out on August 14, followed by 3.11.7, 3.11.8, 3.12.0, 3.12.1 and 3.12.2 between August 24 and September 8. For example, the maintainer published GHSA-pq68-rvw4-xp4r with 3.12.1 on September 3. VulnCheck assigned it CVE-2026-93605 on September 18, and it reached the global database on October 7. The same database already held 19 critical vm2 advisories from January and May 2026.
The bugs, listed on the project's advisory page, fall into a few groups:
- Bypasses of earlier fixes. GHSA-m283-3h24-438v (CVE-2026-47686) showed that host errors carrying
Error.causeleaked objects such asprocess. GHSA-647f-g98j-qq25 then bypassed that fix through call/apply indirection. GHSA-cfcw-xp6x-25gj bypassed an older prototype-mutator fix by adding one more indirect call. - Node.js 26 engine changes. GHSA-27g9-p43v-cw3v and GHSA-wjwh-qqvp-g4p4 escape through Promise species tricks on Node.js 26. The latter says it is reachable from a default
new VM(), with "NoNodeVM,requirepermission, host object injection, or intentionally unsafe configuration" required. - NodeVM policy gaps. The builtin denylist left out
child_process(GHSA-pq68, CVSS 10.0). Other advisories covernode:-prefixed deny entries,node:testexecArgv, an array-shapedrequirethat defeats the nesting guard, native code loaded throughcryptosetEngineandnode:sqlite, and host TLS credentials and trust stores exposed throughhttps. - Host memory. GHSA-fcqc-726x-5wfc lets sandboxed code read and write host memory through Node's shared
Bufferpool.
Most advisories include a working proof of concept. No in-the-wild exploitation has been reported as of October 21, 2026, and none of these CVEs is in CISA KEV.
Who is affected#
Every vm2 release up to 3.12.1 is affected by at least one advisory, and 3.12.2 is the first release with all of them fixed. The risk lands on applications that hand vm2 code they did not write: plugin and extension systems, rule and template engines, workflow and low-code tools, online code runners, and AI agent tools that execute model-generated JavaScript. vm2 had 422,427 downloads in the week of October 13–19, many of them as a dependency of other packages. Some bugs need a particular NodeVM setup (wildcard builtins, nesting, require.external); others work against a plain new VM().
Do you really need to act?#
It depends on who writes the code that vm2 runs. If vm2 is buried in your dependency tree and only evaluates your own trusted code, none of these escapes is reachable. Upgrade normally. If users, tenants, uploaded templates or prompt-injected model output can get code into the sandbox, treat this as urgent. The proofs of concept are short, and a successful escape gets everything the Node process can reach: environment variables, cloud and database credentials, the file system and the network.
Patching is not a long-term answer. The README says that "researchers and security professionals continuously discover new ways to escape the vm2 sandbox". For "completely untrusted sources" it recommends stronger isolation: separate processes or Worker threads with limited permissions, containers or microVMs (Docker, gVisor, Firecracker), managed execution services, or isolated-vm. The README notes that isolated-vm is "in maintenance mode". It also warns: "Do not enable nesting: true for untrusted code," and says not to use vm2 on Bun for untrusted code.
What to do now#
- Inventory:
npm ls vm2 --all,pnpm why vm2oryarn why vm2in every service, and inside built container images. - Upgrade:
npm install vm2@3.12.2. For transitive copies, add"overrides": {"vm2": "3.12.2"}topackage.json, runnpm install, and confirm withnpm ls vm2 --all. Rebuild and redeploy images. - Run untrusted code in a separate low-privilege process, container or microVM with no secrets in its environment.
- Harden in the meantime: drop
builtin: ['*'], never usenesting: true, set an explicitrequire.rootwithrequire.external, and avoid exposing host functions whose errors or promises carry host objects. - If untrusted code ran under an older version, rotate every secret that the Node process could read.
How to tell if you were hit#
No exploitation has been reported, so there are no campaign indicators. The useful evidence is the sandboxed code itself. Search stored or logged submissions for the advisories' primitives: child_process, Error.cause games, __lookupGetter__, Symbol.species, WebAssembly.compileStreaming, setEngine, node:sqlite and node:test. On hosts that ran untrusted code, look for shells or tools (sh, curl, id) spawned by node, unexpected outbound connections, and files written by the app's user.
Timeline#
- — vm2 3.11.6 is released.
- — Five advisories are published, three of them critical (including CVE-2026-47686 and CVE-2026-47698), all fixed in 3.11.6.
- — Fixes keep shipping: 3.11.7 (Aug 24), 3.11.8 (Aug 27), 3.12.0 (Sep 1), 3.12.1 (Sep 3) and 3.12.2 (Sep 8).
- — VulnCheck publishes CVE-2026-93605 for the
child_processdenylist gap. - — 15 more advisories are published, 10 of them critical. Fourteen follow on Oct 5, 8 of them critical.
- — GHSA-pq68-rvw4-xp4r (CVSS 10.0) enters the global advisory database.
Vulnerability records
- CVE-2026-47683 · vm2 is an open source vm/sandbox for Node.js.
- CVE-2026-47686 · vm2 is an open source vm/sandbox for Node.js.
- CVE-2026-47698 · vm2 is an open source vm/sandbox for Node.js.
- CVE-2026-92945 · vm2 before 3.11.7 contains a module allowlist bypass vulnerability in isPathAllowedForModule that uses raw string prefix matching instead of boundary-anchored…
- CVE-2026-92941 · vm2 versions from 3.11.3 before 3.11.7 expose the host tls module to NodeVM sandbox code, allowing attackers to call tls.setDefaultCACertificates() and…
- CVE-2026-92944 · vm2 versions 3.10.2 through 3.11.6 contain a sandbox escape vulnerability on Node.js 26 where Promise.prototype.finally() bypasses vm2's wrapper protections…
- CVE-2026-92939 · vm2 3.11.3 through 3.11.6 exposes the host Node.js crypto module to a NodeVM sandbox when the crypto builtin is allowed.
- CVE-2026-92938 · vm2 versions 3.11.3 through 3.11.6 expose Node.js's host node:sqlite module to code running in NodeVM when that builtin is permitted, either explicitly or…
- CVE-2026-92937 · vm2 3.11.6 is vulnerable to a sandbox escape leading to remote code execution in the host Node.js process.
- CVE-2026-92935 · vm2 is a sandbox for running untrusted Node.js code.
- CVE-2026-92949 · vm2 versions from 3.9.6 before 3.11.7 fail to properly restrict access to accessor properties on frozen objects, allowing sandboxed scripts to bypass…
- CVE-2026-92957 · vm2 through 3.11.6 does not normalize `node:`-prefixed builtin specifiers when evaluating user-supplied negative (deny) entries in a NodeVM wildcard require…
- CVE-2026-92958 · vm2 through 3.11.6 contains a builtin-module denylist bypass in NodeVM.
- CVE-2026-92951 · vm2 before 3.11.7 contains an incorrect authorization vulnerability in the external package allowlist check that uses non-exact substring matching instead of…
- CVE-2026-92940 · vm2 versions 3.11.3 through 3.11.6 expose the host process's real https.globalAgent to sandboxed code when a NodeVM is explicitly configured to allow…
- CVE-2026-92950 · 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.
- CVE-2026-92948 · vm2 versions >= 3.9.6 and <= 3.11.6 are affected by a NodeVM builtin allowlist bypass that permits a sandbox escape on Node.js 24 and newer when the embedder…
- CVE-2026-92952 · vm2 versions 3.11.4 through 3.11.6 incompletely filter Node.js registered internal symbols across the sandbox boundary.
- CVE-2026-92956 · vm2 versions 3.10.1 through 3.11.6 contain a sandbox escape reachable from a default `new VM()` sandbox when running on Node.js 26.
- CVE-2026-92947 · vm2 before 3.11.7 exposes Node's shared Buffer pool to sandboxed code, allowing disclosure of host memory used by Buffer.from, Buffer.concat, and related…
- CVE-2026-92946 · vm2 before 3.11.7 contains a remote code execution vulnerability when require.external is enabled without an explicit require.root that excludes node_modules.
- CVE-2026-92942 · vm2 before 3.11.7 (affected versions <= 3.11.6) does not enforce the VM({ timeout }) option on code executed outside the synchronous VM#run() call.
- CVE-2026-92936 · vm2 versions 3.11.0 through 3.11.6 leak absolute host filesystem paths to sandboxed code through error stack formatting.
- CVE-2026-92933 · vm2 is a sandbox for running untrusted Node.js code.
- CVE-2026-92934 · vm2 before 3.11.8 contains an incomplete fix for Error.cause sanitization that allows sandbox escape when revisited host-wrapped AggregateError objects are…
- CVE-2026-92953 · vm2 versions from 3.11.0 before 3.11.8 fail to protect host TypedArray and ArrayBuffer prototypes from sandbox mutation.
- CVE-2026-92954 · vm2 is a sandbox library for running untrusted JavaScript in Node.js.
- CVE-2026-92955 · vm2 before 3.11.8 contains a sandbox escape vulnerability in NodeVM that allows attackers to access the host __proto__ getter/setter through console._stdout…
- CVE-2026-92959 · vm2 before 3.11.8 does not fully enforce the allowAsync: false option in VM and NodeVM.
- CVE-2026-100723 · vm2 before 3.12.2 does not apply its Buffer backing-store ownership invariant (byteOffset === 0 and buffer.byteLength === length) to Buffers returned from…
- CVE-2026-100722 · vm2 before 3.12.2 does not apply host-side Promise rejection handling in the sandbox-to-host construct trap.
- CVE-2026-100721 · vm2 before 3.12.2 contains an authorization bypass in the NodeVM external-module resolver.
- CVE-2026-93605 · vm2 NodeVM versions before 3.12.1 contain a sandbox escape vulnerability where the DANGEROUS_BUILTINS denylist omits child_process despite blocking other…
Sources
Original sources first: vendor and project advisories, CVE and government records, the discoverers’ write-ups. Every claim above links to one of these. See how the Security Desk works.
Original and primary sources
- vm2 — Security advisories (patriksimek/vm2) github.com
- vm2 — GHSA-pq68-rvw4-xp4r: NodeVM denylist omits child_process (CVE-2026-93605) github.com
- vm2 — GHSA-m283-3h24-438v: Missing Error.cause sanitization (CVE-2026-47686) github.com
- GitHub Advisory Database — GHSA-wjwh-qqvp-g4p4: escape via WebAssembly.compileStreaming (CVE-2026-92956) github.com
- GitHub Advisory Database — GHSA-27g9-p43v-cw3v: escape on Node.js 26 (CVE-2026-92944) github.com
- GitHub Advisory Database API — npm vm2 advisories api.github.com
- CVE record — CVE-2026-93605 cve.org
- CVE record — CVE-2026-47686 cve.org
- vm2 — README (security notes and alternatives) github.com
- npm registry — vm2 package metadata and release times registry.npmjs.org
- npm — vm2 downloads, Oct 13-19, 2026 api.npmjs.org