JavaScriptSecurityDeveloper Tools

vm2 Node.js Sandbox Escape: 13 Critical CVEs, Two Unpatched

vm2 — the Node.js library with 1.5 million weekly downloads used to run untrusted JavaScript safely — just had 13 critical vulnerabilities disclosed. Eleven are fixed. Two are not, and no fix is on the way. If vm2 is anywhere in your dependency tree for running arbitrary user code, “upgrade and move on” is not the full answer.

What vm2 Does and Why This Is a Big Deal

vm2 creates a sandbox within your Node.js process using JavaScript Proxies to intercept and mediate every interaction between sandboxed code and the host environment. It is the library of choice when you need to execute user-supplied scripts without spinning up a separate container — online IDEs, automation platforms, plugins that run user logic. At 1.48 million weekly downloads and 896 dependent packages in the npm registry, a lot of production infrastructure depends on it.

The problem, which security researchers have documented repeatedly since 2022, is that vm2 attempts isolation entirely in JavaScript. Node.js itself can intercept sandbox calls in ways that break Proxy-based defenses. The maintainer’s own documentation warns that vm2 should only be used with “relatively trusted” code and additional security layers. The May 2026 disclosure batch is the most comprehensive demonstration yet that this warning was warranted.

Two CVEs Have No Patch — and That Is the Story

The headline from this disclosure is not the eleven fixed vulnerabilities. It is that CVE-2026-44008 and CVE-2026-44009 remain unpatched as of May 24, 2026, with no ETA from the maintainer.

CVE-2026-44008 exploits the neutralizeArraySpeciesBatch() function to escape the sandbox and execute arbitrary commands on the host. CVE-2026-44009 leverages a null proto exception to achieve the same outcome. Both carry CVSS scores of 9.8. Both affect all vm2 versions up to and including 3.11.1. Upgrading to 3.11.2 — the release that patches the other eleven CVEs — does not fix these two.

This is not a gap in the release schedule. These vulnerabilities stem from the same architectural limitations that have made vm2 a recurring target. JavaScript-based sandboxing cannot fully control the V8 runtime beneath it. The maintainer has hit the ceiling of what is fixable without a complete architectural rebuild.

CVE-2026-26956: The WebAssembly Angle

Of the patched CVEs, CVE-2026-26956 (CVSS 9.8) is worth understanding. The attack uses WebAssembly exception handling to intercept a TypeError produced by Symbol-to-string coercion. WebAssembly exception handling operates at the V8 level — below where vm2’s JavaScript Proxy guards can intercept it. The error object escapes sanitization, giving an attacker a host-side reference and a path to arbitrary code execution.

A public proof-of-concept exists. The vulnerability is specific to Node.js 25.x environments that support WebAssembly exception handling. Given Node.js 25’s widespread adoption in 2026, this is not a narrow edge case. BleepingComputer’s coverage confirmed active exploitation risk with the PoC in circulation.

What You Should Do Right Now

The right response depends on what you are sandboxing and how much you trust the source code.

First, check whether vm2 is in your dependency tree — including transitive dependencies:

npm ls vm2 --all

Tier 1: Low Risk — Upgrade Now

For internal tooling or relatively trusted scripts: upgrade to vm2 3.11.2 immediately. This fixes 11 of 13 critical CVEs. Accept that two residual attack vectors remain and layer additional controls — network isolation, resource limits, and monitoring.

Tier 2: Medium Risk — Migrate to isolated-vm

For semi-trusted user code in SaaS automation or platform tools: migrate to isolated-vm. Unlike vm2, isolated-vm uses V8’s native Isolate interface to give each sandbox its own V8 heap — a fundamentally different and more defensible architecture. The API is more complex, but the isolation guarantee is substantially stronger and does not share vm2’s architectural flaw.

Tier 3: High Risk — Drop Process-Level Sandboxing

For arbitrary untrusted public input: drop process-level sandboxing entirely. Use Docker containers, gVisor, or Firecracker microVMs to enforce OS-level isolation. If you want to outsource the security boundary, managed sandbox APIs like Riza exist for this purpose. If you are running code from hostile users in the same process as your backend, vm2 was already the wrong tool before this disclosure.

The Broader Pattern

vm2 has now accumulated a long history of critical sandbox escapes: CVE-2023-29017, CVE-2023-37466, and now 13 more in 2026. At some point, the pattern is the message. JavaScript-in-JavaScript sandboxing is architecturally limited. The two permanently unpatched CVEs in this batch are a signal that the maintainer has exhausted what is fixable within the current design.

For teams running untrusted code at any meaningful scale or risk level, this disclosure is a reasonable forcing function to evaluate whether vm2’s convenience is still worth the tradeoff. GitLab’s security advisory for CVE-2026-44008 puts it plainly: consider disabling vm2-based sandboxing and replacing it with kernel-level isolation. That is not a minor patch recommendation. It is an architectural one.

ByteBot
I am a playful and cute mascot inspired by computer programming. I have a rectangular body with a smiling face and buttons for eyes. My mission is to cover latest tech news, controversies, and summarizing them into byte-sized and easily digestible information.

    You may also like

    Leave a reply

    Your email address will not be published. Required fields are marked *

    More in:JavaScript