CVE-2026-92941

CVE-2026-92941 is a critical-severity incorrect permission assignment for critical resource vulnerability in vm2 (npm), affecting versions >= 3.11.3, <= 3.11.6. It is fixed in 3.11.7.

Does this CVE actually affect you?

Kodem shows which CVEs are reachable and running in your applications, so you fix what's exploitable, not just what's listed.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Runtime intelligence, not another scanner.

Summary

vm2 NodeVM can replace the host process TLS trust store

vm2 3.11.6 exposes the host tls module to a NodeVM when that builtin is explicitly allowed. Although the module object is wrapped as read-only, its functions still execute against process-wide host state. On Node.js versions that provide tls.setDefaultCACertificates(), sandbox code can replace the certificate authorities trusted by subsequent host-realm TLS clients.

The exploit needs only the narrowly allowed tls and url builtins. It does not require fs, process, module, child_process, an external package, or a general '*' builtin grant. A host HTTPS request rejected an attacker certificate before sandbox execution, then accepted the same certificate and returned an application marker after the sandbox replaced the default CA list.

This crosses the intended sandbox boundary. An attacker can make host HTTPS clients trust an attacker-controlled CA, enabling credential theft and response tampering when the attacker can influence a subsequent destination or network path. Replacing the list also removes the normal trust roots, disrupting unrelated host TLS traffic.

Details

The vulnerable boundary is the default builtin loader in lib/builtin.js. Builtins that are not classified as dangerous are exposed through a recursive read-only bridge:

builtins.set(key, special ? special : vm => vm.readonly(hostRequire(key)));

The read-only wrapper prevents ordinary property assignment through the sandbox proxy. It does not make calls such as tls.setDefaultCACertificates() sandbox-local. That function changes the default CA list for the current Node.js thread and affects subsequent TLS connections that do not provide their own ca option.

The dangerous-builtin list now rejects dns because dns.setServers() mutates process-wide host networking state. It does not reject tls, even though current Node.js exposes an equivalent process-wide trust mutation through it.

A direct call with a normal sandbox array is not necessary. The native TLS function requires an actual host-realm array. The allowed host url module provides one:

const tls = require('tls');
const {URLSearchParams} = require('url');

const hostArray = new URLSearchParams(
  'ca=' + encodeURIComponent(attackerCaPem)
).getAll('ca');

tls.setDefaultCACertificates(hostArray);

URLSearchParams.getAll() executes in the host realm and returns a host array containing the attacker-controlled PEM string. vm2 maps that array into the sandbox. When the mapped value is passed back to the TLS function, the bridge unwraps it to the original host array, satisfying the native type check. The TLS function then replaces the host thread's default CA set.

The complete exploit flow is:

attacker-controlled NodeVM program
  -> require only the allowed tls and url builtins
  -> URLSearchParams.getAll() creates a host array containing attacker CA PEM
  -> bridge unwraps the mapped array when passed back to tls
  -> tls.setDefaultCACertificates() replaces host default trust roots
  -> subsequent host-realm HTTPS client accepts attacker-signed certificates
  -> attacker can observe or modify application TLS traffic

The API is present in Node.js 22.19.0 and later in the 22.x line, and Node.js 24.5.0 and later in the 24.x line.

PoC

The attached PoC is fully local. It creates a temporary CA and a loopback HTTPS server signed by that CA, then performs two requests from the host realm.

  1. Install Node.js 22.19.0 or later in the 22.x line, or Node.js 24.5.0 or later in the 24.x line. OpenSSL must also be available.

  2. In the attached poc directory, run:

    npm install --ignore-scripts
    node poc.js
    
  3. A vulnerable result has all of these properties:

    • the first host request fails with a certificate verification error;
    • the sandbox reports that it supplied one host-realm CA entry;
    • the second host request succeeds with HTTP 200;
    • the second response body is VM2_POC_HOST_TLS_RESPONSE_3e71c8.

The server listens only on loopback and the PoC makes no external request.

Impact

This is an improper sandbox authorization boundary around a process-wide TLS security setting.

An attacker who can submit code to a NodeVM configured with the tls and url builtins can:

  • replace the CAs used by subsequent host-side HTTPS and TLS clients;
  • make the host authenticate services presenting certificates signed by the attacker;
  • intercept host credentials, API tokens, session data, request bodies, and responses when the attacker can influence DNS, routing, a proxy, or a later request destination;
  • modify trusted responses, including configuration, webhook, update, identity, and package-retrieval traffic;
  • remove the normal trusted roots and cause unrelated host TLS connections to fail.

The attacker does not obtain a direct file or command-execution primitive from this PoC. The critical impact is control of the host process's authentication trust decision, outside the sandbox's authority. Connections that explicitly provide their own CA list are not affected, and already cached TLS sessions may remain unchanged.

A file, directory, or other resource is assigned permissions that allow broader access than intended. Typical impact: unauthorized read, modification, or execution of the resource.

CVE-2026-92941 has a CVSS score of 10.0 (Critical). The vector is network-reachable, no privileges required, and no user interaction. A CVSS score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether this affects your application depends on whether the vulnerable code is present and reachable in your environment. A fixed version is available (3.11.7); upgrading removes the vulnerable code path.

Affected versions

vm2 (>= 3.11.3, <= 3.11.6)

Security releases

vm2 → 3.11.7 (npm)

Kodem intelligence

Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.

Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.

Already deployed Kodem?

See it in your environmentNew to Kodem? Get a demo →

Remediation advice

Upgrade vm2 to 3.11.7 or later to resolve this vulnerability.

Kodem Kai can prioritize this vulnerability in your dependency tree and generate a fix recommendation.

Frequently Asked Questions

  1. What is CVE-2026-92941? CVE-2026-92941 is a critical-severity incorrect permission assignment for critical resource vulnerability in vm2 (npm), affecting versions >= 3.11.3, <= 3.11.6. It is fixed in 3.11.7. A file, directory, or other resource is assigned permissions that allow broader access than intended.
  2. How severe is CVE-2026-92941? CVE-2026-92941 has a CVSS score of 10.0 (Critical). This score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether it represents real risk in your environment depends on whether the vulnerable code is present and reachable.
  3. Which versions of vm2 are affected by CVE-2026-92941? vm2 (npm) versions >= 3.11.3, <= 3.11.6 is affected.
  4. Is there a fix for CVE-2026-92941? Yes. CVE-2026-92941 is fixed in 3.11.7. Upgrade to this version or later.
  5. Is CVE-2026-92941 exploitable, and should I be worried? Whether CVE-2026-92941 is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
  6. What actually determines whether CVE-2026-92941 is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
  7. How do I fix CVE-2026-92941? Upgrade vm2 to 3.11.7 or later.

Other vulnerabilities in vm2

Stop the waste.
Protect your environment with Kodem.