CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-92937

CVE-2026-92937: Sandbox Escape leading to Remote Code Execution via Promise Indirection in vm2

Amit Schendel
Amit Schendel
Senior Security Researcher

Oct 2, 2026·6 min read·5 visits

Executive Summary (TL;DR)

A critical bypass in the vm2 sandbox proxy lets untrusted code use Function call/apply indirection to bypass Promise rejection sanitizers, leading to remote code execution.

CVE-2026-92937 is a critical sandbox escape vulnerability in the `vm2` Node.js library. Due to a logical failure in checking direct invocation targets inside the Proxy bridge, an attacker can register Promise callbacks using `Function.prototype.call` or `Function.prototype.apply` indirection. This bypasses the error sanitization wrappers, delivering raw host error objects directly to sandboxed callbacks and allowing the attacker to escape the sandbox and execute arbitrary shell commands on the host.

Vulnerability Overview

The component vm2 is a widely utilized Node.js library designed to run untrusted code in an isolated environment. It attempts to create a secure context boundary by intercepting operations between the host and sandboxed environments through a custom Proxy-based bridge mechanism.

The vulnerability tracked as CVE-2026-92937 represents a critical boundary-crossing flaw where sandboxed code bypasses safety wrapper logic designed to sanitize rejection errors. The vulnerability allows an attacker to leak a raw host-realm error object, bypassing the sandbox isolation guarantees.

Once an attacker obtains a direct reference to a host object from the leaked error, they can abuse standard Node.js API paths to achieve arbitrary remote code execution on the host machine. The vulnerability occurs due to a logical mismatch in how the proxy's apply trap evaluates target execution contexts.

Root Cause Analysis

The root cause of this vulnerability lies in the sanitization logic implemented in lib/bridge.js to address the prior advisory GHSA-m283-3h24-438v. The library used an identity verification gate inside the Proxy bridge apply trap to determine if a call was targeting Promise.prototype.then or Promise.prototype.catch on a host Promise.

When these methods were called directly, the proxy wrapped the registered callbacks in a sanitizer function, which stripped raw host properties from any rejection error. However, the check only inspected the direct target of the invocation represented by the object variable in the apply trap.

By invoking the target methods indirectly using Function.prototype.call or Function.prototype.apply, sandboxed code causes the proxy trap to receive the helper function (e.g., call) as the direct target instead of the underlying then or catch method. Because the target identity does not match the expected Promise prototype methods, the sanitization wrapper bypasses the callbacks entirely, allowing direct access to the raw error object on rejection.

Code Analysis

Prior to the fix, the vulnerability gate inside lib/bridge.js evaluated only the direct target function. The logic was vulnerable to indirect call chains that obscured the identity of the underlying Promise method:

if (!isHost && hostPromiseSanitizeReject !== null) {
    if (isHostPromiseThen(object)) {
        args = wrapHostPromiseThenArgs(args);
    } else if (isHostPromiseCatch(object)) {
        args = wrapHostPromiseCatchArgs(args);
    }
}

The patch addresses this by implementing a structured normalizer function named normalizeHostPromiseCallbacks that executes recursively when the trap fires. The normalizer checks for Function.prototype.call and Function.prototype.apply indirection and unwinds the call stack up to 64 layers to find the true destination function:

function normalizeHostPromiseCallbacks(object, context, args) {
    if (isHost || hostPromiseSanitizeReject === null) return args;
    let curFn = object;
    let curThis = context;
    let container = args;
    let base = 0;
    let guard = 0;
    while (true) {
        if (guard++ >= MAX_PROMISE_PEEL) {
            throw new VMError(OPNA);
        }
        if (isHostPromiseThen(curFn)) {
            wrapPromiseSlot(container, base, false);
            wrapPromiseSlot(container, base + 1, true);
            return args;
        }
        // ... logic continues to peel and sanitize args in place
    }
}

This normalization prevents sandbox code from hiding the identity of the target behind execution helpers, neutralizing variant bypass methods while protecting against time-of-check to time-of-use (TOCTOU) attacks by snapshotting arguments.

Exploitation Methodology

Exploitation requires an async host-realm function exposed to the sandbox that returns a Promise and rejects with an Error containing a custom reference to a host-realm capability. When the sandbox invokes this function, it receives a proxy representation of the Promise.

Instead of registering rejection handlers directly, the exploit invokes the .then or .catch function using Function.prototype.call or Function.prototype.apply. This sequence prevents the proxy from intercepting the callback registration, causing Node's Promise reaction mechanism to invoke the callback with the raw, unsanitized host rejection error:

const p = hostFunction();
p.then.call(p, undefined, (err) => {
    // err contains the unsanitized host error object
    const hostProcess = err.detail;
    hostProcess.mainModule.require('child_process').execSync('id');
});

Because the callback operates with direct reference to the raw host error, the attacker accesses the unmitigated host object properties. By navigating properties such as .detail or .cause, the execution context obtains the native process module, resulting in arbitrary execution of system commands.

Impact Assessment

The security impact of CVE-2026-92937 is critical, achieving the maximum CVSS score of 10.0. A successful exploit breaks all isolation guarantees of the sandbox environment, allowing a remote or local attacker to execute arbitrary shell commands inside the underlying operating system context.

The vulnerability is classified under CWE-94 (Improper Control of Generation of Code) and CWE-693 (Protection Mechanism Failure). Because the sandbox's purpose is to isolate untrusted code, a complete escape represents a total compromise of confidentiality, integrity, and availability on the hosting server.

While there are no current reports of weaponized, active exploits in the wild, public proof-of-concept scripts exist and run reliably. This high severity means any system relying on vm2 to execute untrusted user input is exposed to immediate, full-system takeover if host-provided asynchronous methods return error objects with reference properties.

Mitigation and Remediation

The primary remediation path is updating the vm2 dependency to version 3.11.7 or later. The patch implements complete callback normalization and argument snapshotting, closing the delivery gap and preventing unmitigated error reference leaks.

However, because the vm2 library is officially deprecated and is no longer maintained, continuing to rely on it poses significant long-term security risks. Organizations must transition away from vm2 to alternative isolation techniques.

Recommended alternatives include WebAssembly sandboxing, running code in dedicated short-lived container environments, or using virtualization hypervisors like gVisor or Firecracker. These solutions provide physical boundary separation at the OS or kernel level, making runtime-level sandbox escapes significantly harder to achieve.

Fix Analysis (1)

Technical Appendix

CVSS Score
10.0/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
EPSS Probability
1.03%
Top 37% most exploited

Affected Systems

Node.js applications running vm2 <= 3.11.6

Affected Versions Detail

Product
Affected Versions
Fixed Version
vm2
patriksimek
<= 3.11.63.11.7
AttributeDetail
CWE IDCWE-94, CWE-693
Attack VectorNetwork
CVSS v3.1 Score10.0 (Critical)
EPSS Score0.01033 (1.03%)
Exploit StatusProof of Concept (PoC) available
Patch Version3.11.7

MITRE ATT&CK Mapping

T1059Command and Scripting Interpreter
Execution
T1203Exploitation for Client Execution
Execution
CWE-94
Improper Control of Generation of Code ('Code Injection')

References & Sources

  • [1]Official GitHub Advisory
  • [2]NVD Official CVE Page
  • [3]CVE.org Record
  • [4]Fix Commit
  • [5]Official Version Release (v3.11.7)

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•19 minutes ago•CVE-2026-92938
9.9

CVE-2026-92938: Remote Code Execution in vm2 via node:sqlite DatabaseSync Sandbox Escape

CVE-2026-92938 is a critical sandbox escape vulnerability in the vm2 library (versions 3.11.3 through 3.11.6) that allows arbitrary native code execution on the host when the node:sqlite built-in module is loaded inside a sandboxed NodeVM environment.

Amit Schendel
Amit Schendel
2 views•8 min read
•about 2 hours ago•CVE-2026-92935
9.5

CVE-2026-92935: Remote Code Execution via Array-Shaped Require Config in vm2 NodeVM Sandbox

CVE-2026-92935 is a critical sandbox escape and remote code execution vulnerability in the vm2 library. By supplying an array or exotic object to the require property of NodeVM while nesting is enabled, attackers can bypass security checks, load the host vm2 module, and run arbitrary shell commands on the hosting server.

Alon Barad
Alon Barad
4 views•7 min read
•about 3 hours ago•CVE-2026-92949
4.0

CVE-2026-92949: Sandbox Escape and State Mutation in vm2 via Accessor Property Descriptor Leak

CVE-2026-92949 is a sandbox bypass vulnerability in the vm2 library affecting versions 3.9.6 through 3.11.6. The flaw exists due to a breakdown in the ReadOnlyHandler proxy boundary, allowing sandboxed scripts to obtain direct references to wrapped property setters on frozen host-bound objects, ultimately leading to unauthorized state modification in the host environment. This security failure violates the read-only contract enforced by the sandbox for frozen/readonly objects, though it does not by itself allow a full execution-level realm escape. Due to systemic and structural design difficulties in securing a shared-runtime JavaScript sandbox, the vm2 library has been officially deprecated.

Amit Schendel
Amit Schendel
4 views•7 min read
•about 4 hours ago•CVE-2026-92957
9.9

CVE-2026-92957: Sandbox Escape and Remote Code Execution in vm2 via node: Prefix Policy Bypass

A vulnerability in the NodeVM component of the vm2 sandbox package through version 3.11.6 allows sandboxed code to bypass security policies restricting access to built-in modules. When a wildcard require policy is configured with negative deny entries using the 'node:' prefix (e.g., '-node:child_process'), the parser fails to recognize the exemption due to exact string comparison. As a result, the unmitigated module is registered, allowing sandboxed code to import the host child_process module and execute arbitrary system commands.

Alon Barad
Alon Barad
5 views•6 min read
•about 5 hours ago•CVE-2026-92958
8.5

CVE-2026-92958: Built-in Module Denylist Bypass via fs/promises in vm2 NodeVM Subsystem

CVE-2026-92958 is a high-severity sandbox escape and denylist bypass vulnerability within the NodeVM subsystem of the vm2 sandboxing library. When configuring wildcards with negative deny entries, exact-string matches fail to block subpaths like fs/promises. Sandboxed code can import these subpaths to bypass isolation and execute arbitrary filesystem operations on the host.

Amit Schendel
Amit Schendel
6 views•6 min read
•about 6 hours ago•CVE-2026-92951
9.9

CVE-2026-92951: Sandbox Escape via External Package Allowlist Bypass in vm2

An incorrect authorization and directory traversal vulnerability in the vm2 library before version 3.11.7 allows remote attackers to bypass the sandbox's external package allowlist. This flaw permits sandboxed code to resolve and execute arbitrary packages available on the host filesystem under host privileges, leading to unauthenticated sandbox escape and host code execution.

Alon Barad
Alon Barad
6 views•6 min read