New Sandbox Escape Affecting Popular nodejs Sandbox library vm2

Popular Node.js sandboxing library vm2 has just announced a critical vulnerability in their library which allows attackers to bypass their promise sanitization and execute arbitrary code, escaping the sandbox. This is a critical vulnerability with a 9.8 CVSS score, any application leveraging vm2 to run untrusted node.js code needs to upgrade immediately to v3.10.2.

January 27th, 2026
Share

Popular Node.js sandboxing library vm2 has just announced a critical vulnerability in their library which allows attackers to bypass their promise sanitization and execute arbitrary code, escaping the sandbox. This is a critical vulnerability with a 9.8 CVSS score, any application leveraging vm2 to run untrusted node.js code needs to upgrade immediately to the latest version

This is not the first time vm2 has been caught up in a critical CVE, and back in July another batch of vulnerabilities were discovered. Back then the readme was updated to call out the discontinuation of the library, but this has not stopped the popularity of the library as there are many situations where vm2 may be appropriate. 

While many of these use cases will only be internal only and never be used to run untrusted code. As this can be exploited with a relatively simple exploit that is already publicly available and many internal-only tools can eventually run untrusted input, we are recommending that anyone using vm2 should update immediately to version 3.10.2.

If you are a semgrep customer you can search for the package in your dependencies using the package search tool and a rule is now available for this vulnerability and can be found by starting a full scan from the Projects tab (Managed Scan users), in your CI, or locally. 

How to tell if you are affected

vm2 is a library that helps sandbox untrusted javascript code, using node’s internal proxying tools. While many uses of vm2 are rarely exposed publicly and instead are used for internal tools, depending on the exact architecture sometimes it is possible to access these tools from publicly available applications and tools.

Therefore anyone who uses 3.10.1 or earlier should consider themselves affected. To respond and resolve this vulnerability simply update to 3.10.2. If you are a semgrep customer you can use this URL to directly check in Semgrep if you are affected. As this is a remote code execution vulnerability, you should be on the lookout for any post-exploitation activity.

If you are using vm2 for arbitrary, untrusted user submitted code, vm2 is probably not an appropriate tool, instead consider tools that isolate untrusted code from your current application’s nodejs process such as the maintainer recommended isolated-vm or containerized applications.
Breaking into JavaScript with vm2

If you are a recent inductee into the JS ecosystem, let’s get you up to speed. VM2 is a popular lightweight sandboxing solution for running untrusted Javascript code. This allows tools like Replit, that allow users to experiment with code in the browser. It does this via Node’s internal proxying feature to allow you to sandbox untrusted code within your application’s own Node process. This makes sandbox escapes Very Bad - it allows untrusted arbitrary javascript in the context of your Node process, inheriting whatever access and/or privileges that process may have.

Breaking into JavaScript with vm2

From a mile high view, VM2 works by using JavaScript proxies to instrument (and control access to) potentially dangerous behavior. As part of sandbox setup for promises, proxy hooks use helper functions to remove attempts to modify global objects. Unfortunately, in affected versions, the configuration for promise catch blocks had a fail-open case where this safeguard was not applied to global promise handlers.

A malicious user can specify a global promise exception handler by specifying an unscoped promise.catch(...) that JS will then hoist into the global scope, bypassing the local scope promise sanitizer. The GHSA has PoC code, which we are posting here in its entirety so readers can appreciate the ease with which this can be exploited in affected sandboxes.

const { VM } = require("vm2");

const code = `
const error = new Error();
error.name = Symbol();
const f = async () => error.stack;
const promise = f();
promise.catch(e => {
    const Error = e.constructor;
    const Function = Error.constructor;
    const f = new Function(
        "process.mainModule.require('child_process').execSync('echo HELLO WORLD!', { stdio: 'inherit' })"
    );
    f();
});
`;

new VM().run(code);

That’s it. Simple global promise with arbitrary JS. This simplicity is what makes this vulnerability so dangerous. From this access an attacker could do anything the node process can do, such as reading memory values from the node process, to running arbitrary code in exec or spawning child processes. This is why back in July the maintainers considered the project discontinued, running arbitrary code like this will always be inherently risky and there will always be bypasses to sanitization. While the maintainers do intend to keep up with all the various bypasses and fix these issues when they occur, it is very much like playing whack-a-mole.

We Need Isolation

When developing applications that explicitly run user-provided code, while every effort should be made to isolate it rather than rely on sanitization. In July Semgrep security researcher Max Vonblankenburg wrote (after a year of critical vulnerabilities affecting vm2) about the discontinuation of vm2.

Back then the vm2 discontinuation statement really wasn't a surprise to those paying close attention. Eight security advisories in a single year, seven of these within just a four-month window, revealed a pattern that couldn't be patched away. The core issue, as contributor XmiliaH explained at the time, was architectural: Node itself intercepts calls from the sandbox, preventing arguments from being properly wrapped in proxies. When your isolation mechanism depends on a foundation that actively undermines it, no amount of fixing will make it secure.

Instead of relying on the problematic vm model, the successor to vm2, isolated-vm relies on V8’s native Isolate interface, which offers a more solid foundation, but even then the maintainers of vm2 stress the importance of isolation and actually recommend docker with logical separation between components.

About

semgrep logo

Semgrep enables teams to use industry-leading AI-assisted static application security testing (SAST), supply chain dependency scanning (SCA), and secrets detection. The Semgrep AppSec Platform is built for teams that struggle with noise by helping development teams apply secure coding practices.