A critical vulnerability has been patched in vm2, a widely used library for the Node.js JavaScript runtime that allows untrusted code to be executed inside a sandbox within the same process as trusted application code. The flaw allows for a sandbox escape, which is as serious as it gets for a software component whose primary goal is enforcing a security boundary between trusted and untrusted code.

The vm2 library, which is listed as a dependency by almost 900 other packages on NPM and many projects on GitHub, is not a stranger to sandbox escape vulnerabilities. In fact, in July 2023, its creator decided to stop maintaining the project and deprecate it after one such vulnerability.

Despite the project being unmaintained, in the absence of good alternatives, people have kept using it, leading to millions of downloads every month. In October 2025, the original maintainer decided to resurrect the project after patching all past vulnerabilities and announcing plans to rewrite it in TypeScript.

The new vulnerability patched this week is tracked as CVE-2026-22709 and affects versions older than 3.10.2. Users are advised to upgrade to the latest version as soon as possible.

“In vm2 for version 3.10.0, Promise.prototype.then Promise.prototype.catch callback sanitization can be bypassed,” the official advisory reads. “This allows attackers to escape the sandbox and run arbitrary code.”

Sandboxing is a cat-and-mouse game

Sandboxes like vm2 are needed by web and other Node-based applications whose functionality enables users or tools to upload and execute scripts. Because user-controlled code is untrusted by nature, it cannot be allowed to execute in the same context as the application itself. Yet the host application needs to monitor and see what the code does.

The vm2 library achieves this through a complex network of proxies that intercept and mediate interactions between the sandbox and the host environment. But the complexity of JavaScript means there will likely always be a way to trick this chain of proxies.

The project is honest about this in its description: “Objects can be accessed through prototype chains, constructors can be reached via error objects, symbols provide protocol hooks, and async execution creates timing windows. The sheer number of ways to traverse from one object to another in JavaScript makes building an airtight in-process sandbox extremely difficult.”

The maintainer clearly warns that new bypasses will likely be discovered in the future and while they will be patched, the cat-and-mouse game will continue. In his announcement about the project’s resurrection in October, he noted that he hopes AI-assisted vulnerability detection will help catch more of these issues in the future.

There are other alternatives to isolate code that would provide stronger security guarantees, such as full process sandboxing, virtual machines, containers, and more. But they come with heavier performance costs or add other complexities and hurdles. Not to mention, those approaches are not vulnerability-free either.

The maintainer advises that vm2 should only be used when:

  • You need tight integration with host objects and fast synchronous communication
  • The untrusted code comes from a relatively trusted source (e.g., internal tools, plugin systems with vetted authors)
  • You combine vm2 with other security layers (network isolation, filesystem restrictions, resource limits)
  • You accept the risk and actively monitor for security updates

Read More