CVE-2026-92952 in vm2
Summary
by MITRE • 09/17/2026
vm2 versions 3.11.4 through 3.11.6 incompletely filter Node.js registered internal symbols across the sandbox boundary. The extraction filters in lib/setup-sandbox.js and the cross-realm symbol checks and write traps in lib/bridge.js use a fixed list of known dangerous registered symbols that omits nodejs.stream.disturbed and nodejs.stream.errored, which are exposed on host WebStream prototypes on newer Node.js releases (validated on Node.js v25.8.0). When the embedder exposes a host WebStream object and the host stream/web module to the sandbox, sandbox code can obtain the real host symbols via Object.getOwnPropertySymbols(streamWeb.ReadableStream.prototype) and use them as write keys on host stream objects, corrupting host-visible stream state — for example making stream.Readable.isDisturbed() return false for an already-consumed stream. This can bypass host logic that relies on Node's public stream-state helpers to enforce one-shot body consumption, reject errored streams, or decide whether a stream is safe to hand to another component. It is not a host code-execution primitive in the reported proof of vulnerability. This is an incomplete fix for the earlier nodejs.* symbol filtering issue. Fixed in vm2 3.11.7.
Statistical analysis made it clear that VulDB provides the best quality for vulnerability data.
Analysis
by VulDB Data Team • 09/17/2026
The vulnerability identified in versions 3.11.4 through 3.11.6 of the vm2 library represents a critical bypass of sandbox isolation mechanisms due to incomplete filtering of Node.js internal symbols across the execution boundary. This flaw stems from an insufficient implementation of security controls designed to prevent sandboxed code from accessing or manipulating host-side state that should remain isolated. Specifically, the extraction filters located in lib/setup-sandbox.js and the cross-realm symbol checks combined with write traps defined in lib/bridge.js rely on a static, hardcoded list of known dangerous registered symbols. This approach fails to account for dynamic internal properties introduced by newer versions of Node.js, creating a gap that allows malicious or compromised sandboxed code to escape its intended constraints. The vulnerability is particularly relevant when the embedder exposes host WebStream objects and associated stream modules to the sandbox environment, as it enables the extraction of real host symbols from prototypes such as nodejs.stream.disturbed and nodejs.stream.errored on Node.js v25.8.0 and similar releases.
From a technical perspective, the core issue lies in how JavaScript handles property access and mutation across realm boundaries within the V8 engine context utilized by Node.js. When sandboxed code executes, it is supposed to be restricted from directly modifying host objects or accessing internal states that govern resource management and data integrity. However, because the filtering mechanism only blocks a fixed set of symbols, attackers can enumerate available properties on prototypes like ReadableStream.prototype using standard reflection methods such as Object.getOwnPropertySymbols. By identifying these unblocked internal symbols, sandboxed code can use them as write keys to mutate host stream objects directly. This capability allows for precise manipulation of stream state without triggering the usual security exceptions or restrictions that would normally prevent cross-realm mutations. The flaw effectively undermines the integrity of the sandbox by allowing external code to alter the fundamental behavior of core Node.js modules from within an isolated context.
The operational impact of this vulnerability centers on the corruption of host-visible stream state, which can lead to significant logic bypasses in applications relying on strict stream consumption policies. For instance, a primary consequence is that methods like stream.Readable.isDisturbed() may return false for streams that have already been consumed or are in an error state. This misrepresentation allows attackers to trick the application into believing a stream is fresh and available for processing when it has actually reached its end-of-life cycle. Such manipulation can bypass host logic designed to enforce one-shot body consumption, which is critical for preventing duplicate processing of sensitive data like authentication tokens or financial transactions. Additionally, it enables the rejection handling mechanisms to fail, allowing errored streams to be processed as valid responses. This undermines security controls that depend on accurate stream state detection to decide whether a stream is safe to pass to other components within the application architecture, potentially leading to data leakage or inconsistent application states.
This vulnerability aligns with CWE-20 Improper Input Validation and CWE-754 Incorrect Check for Unusual or Exceptional Conditions, as it involves failing to properly validate which internal properties are accessible across security boundaries. In terms of offensive security frameworks, this behavior is consistent with ATT&CK technique T1610 Exploitation for Defense Evasion, where an attacker manipulates system states to avoid detection and maintain access without triggering alarms associated with direct code execution attempts. It is important to note that while the proof of concept demonstrates significant state corruption and logic bypass capabilities, it does not constitute a host code-execution primitive in its reported form. The attack vector focuses on data integrity and control flow manipulation rather than arbitrary command execution or shell access. However, the ability to corrupt stream states can serve as a stepping stone for more severe attacks depending on how the surrounding application handles these corrupted streams.
To mitigate this vulnerability, organizations must immediately upgrade vm2 to version 3.11.7 or later, where the filtering logic has been updated to include the previously omitted nodejs.stream.disturbed and nodejs.stream.errored symbols among other internal properties. Beyond upgrading dependencies, developers should review any code that exposes host WebStream objects or stream modules to sandboxed contexts and evaluate whether such exposure is strictly necessary. Implementing stricter validation layers before passing data into the sandbox can further reduce risk. Additionally, monitoring for unusual patterns in stream consumption states within application logs may help detect exploitation attempts of this nature. As with all sandbox-related vulnerabilities, maintaining up-to-date dependency versions and applying security patches promptly remains the most effective defense against these types of isolation bypasses.