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-92941

CVE-2026-92941: Sandbox Escape and Process-Wide TLS Trust Store Manipulation in vm2

Amit Schendel
Amit Schendel
Senior Security Researcher

Oct 2, 2026·10 min read·1 visit

Executive Summary (TL;DR)

A critical flaw in vm2 (3.11.3-3.11.6) allows sandboxed code to bypass isolation and overwrite the global Node.js root CAs, enabling complete Man-in-the-Middle compromise of outbound host HTTPS connections.

CVE-2026-92941 is a critical sandbox-escape and trust-manipulation vulnerability in the vm2 library (versions 3.11.3 to 3.11.6). This security flaw allows untrusted code executing within a NodeVM sandbox environment to compromise the global TLS trust store of the host Node.js process. By leveraging a design flaw where the host's native 'tls.setDefaultCACertificates' can be executed via a proxy wrapper, combined with a bridge unwrapping bypass in the 'url' module, an attacker can modify the process-wide default root Certificate Authorities. Consequently, all subsequent outbound TLS/HTTPS clients running on the host thread are forced to trust attacker-signed certificates, facilitating transparent Man-in-the-Middle (MitM) attacks. The vulnerability was resolved in version 3.11.7 of vm2 by introducing built-in member-level sanitization before applying read-only proxy wrappers.

Vulnerability Overview

The sandboxing library vm2 provides an isolated context within Node.js to execute untrusted code. To facilitate interaction with the outside host environment, developers can explicitly authorize the loading of built-in modules like tls and url. When these modules are loaded, vm2 wraps them in a read-only Proxy to prevent sandboxed code from modifying their properties or inserting malicious bindings directly. However, this Proxy architecture does not restrict method execution, creating an attack vector when a permitted module contains a function that alters global process state rather than instance properties.

CVE-2026-92941 is a critical vulnerability affecting vm2 versions 3.11.3 through 3.11.6. It allows sandboxed JavaScript scripts to escape isolation and manipulate the global TLS trust store of the host process. This vulnerability is classified under CWE-732 (Incorrect Permission Assignment for Critical Resource) and carries a CVSS base score of 10.0. The vulnerability relies on the presence of the tls and url built-ins in the NodeVM instance, enabling attackers to replace the default Certificate Authority (CA) root certificates of the host.

The cryptographic consequence of this vulnerability is significant. Any subsequent TLS or HTTPS connection initiated by the host Node.js process will rely on the compromised root CA store. If an attacker controls the newly injected CA certificates, they can execute transparent man-in-the-middle attacks on the host process's outbound traffic. This allows for session hijacking, credential harvesting, and remote command execution if the host downloads and executes serialized data or updates from external services.

This report details the architectural failure that allowed sandboxed code to influence process-wide cryptographic configuration. It analyzes the specific bridge unwrapping bypass that circumvented native type enforcement. Finally, it outlines the official remediation, evaluates the long-term viability of the patch, and provides concrete mitigation and detection rules to identify active exploitation.

Root Cause Analysis

The core architecture of vm2 relies on ES6 Proxies to enforce a boundary between the sandbox and the host. When a module is loaded via hostRequire, vm2 executes the vm.readonly(hostRequire(key)) method to wrap the module. The proxy intercepts property mutations (set, defineProperty, deleteProperty), returning errors when sandboxed code attempts to alter the module. However, the proxy is transparent to method invocation, meaning calling a method on the proxy forwards the execution back to the host realm with the host process's full privilege set.

This mechanism fails to maintain sandboxing invariants when exposed to APIs that mutate process-level settings. The native Node.js tls.setDefaultCACertificates method is a process-wide API that alters the root CA trust store inside the underlying OpenSSL library. Since vm.readonly only prevents property mutation on the tls module export object, it does not intercept or restrict the calling of setDefaultCACertificates. This allows sandboxed code to execute the method and target the host process configuration directly.

Although sandboxed code can call the method, native Node.js methods execute strict type checks on arguments within C++ space. The tls.setDefaultCACertificates method expects an array of strings representing PEM-encoded certificates. If a sandboxed array is passed, the native runtime detects that the object is a proxy-wrapped sandbox array rather than a native host-realm array, throwing a type error. This type enforcement acts as a secondary barrier that normally prevents host process manipulation from within the sandbox.

To execute a successful sandbox escape, an attacker must bypass this marshalling constraint by obtaining a raw, unwrapped host-realm array. Because vm2 maintains performance by dynamically unwrapping certain host-originated structures, developers must carefully vet all methods on allowed modules. The combination of unchecked process-wide configuration methods and implicit object unwrapping allows malicious scripts to circumvent security assumptions and alter host settings.

The Bridge Unwrapping Trick

The critical bypass that enables exploitation of CVE-2026-92941 involves leveraging the native url module to forge a host-realm array. Under normal operation, the vm2 bridge translates objects between the host and sandbox environments. If a host-native function returns an object to the sandbox, the bridge intercepts the transfer. However, when certain built-in objects are returned, vm2 must unwrap them during subsequent calls back to the host to maintain compatibility with native internal APIs.

The URLSearchParams.prototype.getAll method satisfies the precise requirements needed to craft an exploit payload. When called, it produces a standard JavaScript array containing query parameter values. Because url is a host-native module, the array returned by getAll is allocated in the host realm. Although the sandboxed environment receives a reference to this array, the underlying object remains a genuine host-realm array, which vm2 recognizes.

When the sandboxed script passes this host-originated array back to tls.setDefaultCACertificates, the vm2 bridge performs automatic unwrapping. The bridge extracts the underlying host-realm array reference to satisfy the expectations of the native C++ function. Because the unwrapped object is a genuine, native host-realm array, the C++ validation logic inside Node.js passes without error, allowing the malicious PEM certificate payload to be accepted as the new default CA list.

This interaction highlights the complexity of enforcing security boundaries in mixed-realm environments. A security boundary is only as strong as its weakest bridge mapping. By combining an allowed module that modifies global state with an allowed module that returns unwrapped native containers, the attacker constructs a complete chain of execution that subverts both the proxy-based write protection and the native runtime type checks.

Exploitation Methodology

To exploit this vulnerability, the target application must run a vulnerable version of vm2 with a configuration that allows both the tls and url built-in modules. This configuration is common in applications that handle external network requests or perform URL parsing and network client operations. The attacker must have the ability to supply arbitrary JavaScript code for execution within the sandboxed context, which is typical in plug-in platforms, code-evaluation APIs, and serverless runtimes.

The exploit sequence begins by encoding the malicious root Certificate Authority PEM block into a format suitable for URL query parameters. The sandboxed code instantiates a URLSearchParams object with this payload, then invokes getAll to retrieve the PEM block within a host-realm array. Finally, the sandboxed code invokes tls.setDefaultCACertificates, passing the retrieved array to overwrite the default trust anchor list of the process.

Upon successful execution, the entire Node.js thread or process immediately shifts to the new cryptographic trust anchors. The previous root certificates provided by the operating system or Node.js bundle are completely replaced. Any subsequent outbound connections established using standard TLS clients, including native https or library-based clients like axios that use the default CA store, will trust certificates signed by the attacker's newly injected CA.

In a typical attack scenario, the attacker pairs this trust-store manipulation with network interception techniques such as DNS spoofing or ARP poisoning. Once the host process attempts to contact an external service, the attacker intercepts the connection and supplies a certificate signed by the rogue CA. The host process accepts the certificate as valid, enabling the attacker to decrypt sensitive transaction data, steal API tokens, or inject malicious payloads into subsequent server responses.

Downstream Impact and Cryptographic Implications

The impact of process-wide TLS trust store compromise is extensive and difficult to isolate. In modern cloud environments, Node.js applications frequently interact with metadata services, database endpoints, identity providers, and API gateways. When the trust store is compromised, the confidentiality and integrity of all these channels are undermined, transforming a local sandbox escape into a broad network security failure.

Because tls.setDefaultCACertificates alters the OpenSSL configuration for the entire process, the impact is not limited to the execution context of the sandbox. Even if the sandbox is terminated or the script execution finishes, the modified CA store persists for the remaining lifecycle of the host Node.js process. Any other unrelated request handler or application module executing on the same host will use the corrupted CA store, magnifying the scope of the vulnerability.

Furthermore, detecting this mutation from application logs is challenging. Standard application monitoring tools typically log HTTP request URLs and response times, but do not inspect the details of the TLS handshake or the specific CA path used to validate a connection. This lack of visibility means that an active man-in-the-middle attack facilitated by this vulnerability can persist undetected for long periods, leading to silent, ongoing data exfiltration.

The CVSS score of 10.0 reflects this severity. The attack requires no privileges, can be executed remotely if the application evaluates untrusted scripts, and has a high impact on confidentiality and integrity. The only limitation is the availability of both tls and url modules, which are frequently allowed together due to their joint utility in processing web requests and handling callbacks.

Remediation and Patch Analysis

The vulnerability was resolved in version 3.11.7 of vm2 by implementing a defensive sanitization layer in lib/builtin.js. The maintenance team introduced a dictionary of member-level sanitizers, called BUILTIN_MEMBER_SANITIZERS. Before a permitted module is wrapped in the read-only Proxy and returned to the sandbox, it must pass through this sanitization pipeline to neutralize dangerous process-wide methods.

The specific patch for the tls module, implemented in sanitizeTlsModule, intercepts the exported object and replaces setDefaultCACertificates with a stub function. When sandboxed code attempts to call this method, the stub executes instead of the native function, throwing an error indicating that the method is disabled due to security concerns. This blocks the attack vector at the module-exposure level, ensuring the native C++ method is never reachable from the sandboxed environment.

// Neutralizing setDefaultCACertificates inside lib/builtin.js
function sanitizeTlsModule(mod) {
	if (typeof mod.setDefaultCACertificates !== 'function') return mod;
	const copy = Object.assign({}, mod);
	copy.setDefaultCACertificates = function setDefaultCACertificates() {
		throw new Error('tls.setDefaultCACertificates is disabled in vm2 sandboxes: it replaces the host process default CA trust store (GHSA-98xx-8mx4-x7cm).');
	};
	return copy;
}

While the fix is highly effective for tls.setDefaultCACertificates, blocklist-based sanitization has inherent limitations. If Node.js introduces new global configuration methods in other built-in modules, or if an existing method was overlooked, the sandbox remains potentially vulnerable. This highlights the difficulty of maintaining a secure sandbox in a complex, rapidly evolving runtime environment like Node.js, where native bindings continuously expand the attack surface.

Due to the repeated discovery of critical sandbox escape vectors, the vm2 library has been officially deprecated. The maintainers acknowledge that the architecture of wrapping Node.js APIs in ES6 Proxies cannot guarantee complete isolation against determined attackers. Organizations must migrate to robust isolation patterns, such as isolating untrusted code in separate operating system processes, micro-VMs, or WebAssembly execution environments.

Official Patches

Patrik SimekSecurity fix commit aa146a77f859325e079f3bfbfe6d8309af483daa
Patrik SimekRelease 3.11.7 containing the patch for CVE-2026-92941

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:L
EPSS Probability
0.29%
Top 81% most exploited

Affected Systems

Applications utilizing the vm2 Node.js library configured with a NodeVM instance that permits access to both 'tls' and 'url' built-in modules.

Affected Versions Detail

Product
Affected Versions
Fixed Version
vm2
Patrik Simek
>= 3.11.3, < 3.11.73.11.7
AttributeDetail
CWE IDCWE-732
Attack VectorNetwork / Code Execution Boundary
CVSS Score10.0
EPSS Score0.00289
ImpactProcess-Wide TLS Trust Store Compromise
Exploit Statuspoc
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1222File and Directory Permissions Modification
Defense Evasion
CWE-732
Incorrect Permission Assignment for Critical Resource

The product specifies permissions for a security-critical resource in a way that allows that resource to be accessed or modified by unauthorized actors.

Known Exploits & Detection

GitHub Security AdvisoryDetailed advisory documentation including proof-of-concept explanation.

Vulnerability Timeline

Remediation code patch committed to the vm2 repository.
2026-08-22
CVE-2026-92941 published in registry.
2026-09-17
GitHub Advisory GHSA-98xx-8mx4-x7cm disclosed publicly.
2026-09-17
NVD analyzed and assigned critical CVSS score of 10.0.
2026-09-17
Vulnerability metadata populated across secondary threat vulnerability indexes.
2026-09-19

References & Sources

  • [1]CVE.org Record
  • [2]NVD Record
  • [3]GitHub Security Advisory
  • [4]Official Remediation Commit
  • [5]Official 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

•4 minutes ago•CVE-2026-92945
4.2

CVE-2026-92945: Sandbox Escape and Module Allowlist Bypass via Path Prefix Matching in vm2

A module allowlist bypass vulnerability (CVE-2026-92945 / GHSA-7q3f-wx44-378m) was identified in the vm2 sandboxing library prior to version 3.11.7. This flaw permits unauthenticated or untrusted code running within the sandbox environment to bypass explicit module restrictions. When the transitive resolution option is disabled, the system fails to validate file system path boundaries, allowing prefix-sharing sibling directories to be resolved and loaded, thereby escaping intended sandbox restrictions.

Amit Schendel
Amit Schendel
0 views•6 min read
•about 2 hours ago•CVE-2026-92944
9.8

CVE-2026-92944: Sandbox Escape in vm2 via Stale V8 PromiseThenLookupChain Protector

A critical engine-level reachability failure in Node.js 26 running V8 14.6 allows attackers to escape the vm2 sandbox environment. When consecutive prototype properties are modified using sequential assignments, a V8 optimization bug fails to invalidate the PromiseThenLookupChain protector. By calling Promise.prototype.finally, the attacker bypasses the vm2 wrappers, hijacks the promise reaction using a custom constructor, triggers a calibrated stack overflow to capture a host-realm RangeError, and executes arbitrary shell commands on the host.

Alon Barad
Alon Barad
3 views•8 min read
•about 3 hours ago•CVE-2026-92939
9.9

CVE-2026-92939: Critical Sandbox Escape via Host Crypto setEngine Native Code Execution in vm2

A critical sandbox escape vulnerability in the vm2 library allows sandboxed JavaScript code to bypass containment and execute arbitrary native code on the host process. This occurs when the host's builtin crypto module is exposed to the NodeVM environment. Although vm2 implements a read-only proxy layer to restrict direct modifications to host properties, it does not prevent invocation of host-level functions. By calling the crypto.setEngine API with a path to a malicious native library on disk, an attacker can trigger OpenSSL's dynamic module loader. The host's operating system loader immediately runs the dynamic library's initializers/constructors before verifying engine compatibility, leading to remote code execution in the context of the host process.

Amit Schendel
Amit Schendel
4 views•5 min read
•about 4 hours 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
6 views•8 min read
•about 5 hours ago•CVE-2026-92937
10.0

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

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.

Amit Schendel
Amit Schendel
6 views•6 min read
•about 6 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
5 views•7 min read