Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-47209

CVE-2026-47209: vm2 Node.js Information Disclosure Flaw

CVE-2026-47209 is an information disclosure vulnerability in vm2, an open source sandbox for Node.js. The flaw allows attackers to bypass security controls via proxy inheritance. This article covers technical details, affected versions, impact, and mitigation steps.

Published:

CVE-2026-47209 Overview

CVE-2026-47209 affects vm2, an open source virtual machine and sandbox library for Node.js. The vulnerability resides in the BaseHandler.set trap in bridge.js at line 1231, which ignores the receiver parameter and unconditionally writes to the host target object. Attackers can exploit this flaw to write dangerous cross-realm Symbol keys, such as nodejs.util.promisify.custom, to host objects from within the sandbox. The bug provides an alternative attack vector that bypasses per-trap isDangerousCrossRealmSymbol guards on the direct set path. The vm2 maintainers patched this issue in version 3.11.4.

Critical Impact

Sandboxed code can write attacker-controlled properties onto host objects, breaking sandbox integrity and enabling cross-realm symbol injection that may lead to sandbox escape.

Affected Products

  • vm2 versions prior to 3.11.4
  • Node.js applications embedding vm2 for untrusted code execution
  • Server-side platforms relying on vm2 for sandboxed JavaScript evaluation

Discovery Timeline

  • 2026-06-12 - CVE-2026-47209 published to NVD
  • 2026-06-17 - Last updated in NVD database

Technical Details for CVE-2026-47209

Vulnerability Analysis

The vm2 library bridges values between the host realm and the sandbox realm using JavaScript Proxy handlers. The BaseHandler.set trap is responsible for property writes that originate inside the sandbox and target host objects. According to the ECMAScript Proxy set trap specification, when receiver !== proxy, the assignment must create an own property on the receiver rather than on the proxy target. The vm2 implementation discards the receiver parameter and calls otherReflectSet(object, key, value) against the host target directly. This issue is categorized under [CWE-693] Protection Mechanism Failure.

Root Cause

The root cause is incorrect Proxy invariant handling in bridge.js. When a child object inherits from a vm2 proxy via Object.create, writes to that child should land on the child, not the proxy target. By ignoring receiver, vm2 routes every inherited write through to the host object. This breaks the boundary between sandbox-owned and host-owned state and circumvents guards that only inspect the direct set path.

Attack Vector

An attacker controlling code inside the vm2 sandbox creates an object that inherits from a bridged host object. Assigning a cross-realm Symbol key, such as nodejs.util.promisify.custom, to the inheriting child triggers the buggy set trap. The write leaks through to the host object, planting an attacker-controlled property that host code later consumes. This vector evades any future isDangerousCrossRealmSymbol guard installed only on the direct set path, because the dangerous write reaches the host through inherited assignment instead.

No verified public exploit code is available. See the GitHub Security Advisory GHSA-c4cf-2hgv-2qv6 and the GitHub Commit Update for the authoritative technical description.

Detection Methods for CVE-2026-47209

Indicators of Compromise

  • Unexpected presence of cross-realm Symbol properties such as nodejs.util.promisify.custom on objects that originated in host code
  • Node.js processes embedding vm2 versions below 3.11.4 in production dependency manifests
  • Sandbox child processes spawning unexpected host commands shortly after evaluating untrusted scripts

Detection Strategies

  • Scan application package.json and package-lock.json files for vm2 dependencies pinned below version 3.11.4
  • Inspect runtime behavior of vm2-hosting services for anomalous property writes that target host-owned objects
  • Correlate sandbox evaluation events with subsequent process, file, or network activity originating from the host Node.js process

Monitoring Recommendations

  • Enable verbose logging around vm2 run and runFile invocations to capture untrusted input prior to evaluation
  • Track outbound network connections and child process creation from Node.js services that evaluate user-supplied JavaScript
  • Alert on Software Composition Analysis (SCA) findings that flag vm2 versions prior to 3.11.4 in build pipelines

How to Mitigate CVE-2026-47209

Immediate Actions Required

  • Upgrade vm2 to version 3.11.4 or later across all Node.js services that evaluate untrusted code
  • Audit application dependency trees for transitive vm2 usage and update affected packages
  • Treat vm2 as deprecated where feasible and plan migration to maintained isolation primitives such as isolated-vm or worker processes with OS-level sandboxing

Patch Information

The maintainers fixed the issue in vm2 version 3.11.4. Review the GitHub Release v3.11.4 notes and the GitHub Commit Update implementing the fix. The patch corrects the BaseHandler.set trap to honor the receiver parameter consistent with the Proxy specification.

Workarounds

  • Restrict the categories of input passed to vm2 so that arbitrary JavaScript from untrusted sources cannot reach the sandbox
  • Run vm2-hosting services under least-privilege OS accounts with seccomp, AppArmor, or container-level restrictions to limit blast radius
  • Isolate untrusted code execution in dedicated short-lived processes that are terminated after each evaluation
bash
# Configuration example
npm install vm2@^3.11.4
npm ls vm2

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.