CVE-2026-92941
vm2 3.11.3 before 3.11.7 TLS Trust Store Manipulation
vm2 versions from 3.11.3 before 3.11.7 expose the host tls module to NodeVM sandbox code, allowing attackers to call tls.setDefaultCACertificates() and replace process-wide certificate authorities. Attackers with access to allowed tls and url builtins can use URLSearchParams to create host-realm arrays and manipulate the TLS trust store, enabling subsequent host HTTPS clients to accept attacker-controlled certificates.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- High
- Integrity
- High
- Availability
- Low
Exploit likelihood
What each source reports
CVE List Score used
10.0
vm2 3.11.3 before 3.11.7 TLS Trust Store Manipulation
vm2 versions from 3.11.3 before 3.11.7 expose the host tls module to NodeVM sandbox code, allowing attackers to call tls.setDefaultCACertificates() and replace process-wide certificate authorities. Attackers with access to allowed tls and url builtins can use URLSearchParams to create host-realm arrays and manipulate the TLS trust store, enabling subsequent host HTTPS clients to accept attacker-controlled certificates.
- Record
CVE-2026-92941- CVSS 4.0
- 10.0 Critical
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:L/SC:H/SI:H/SA:L - CVSS 3.1
- 10.0 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:L - Weakness
- CWE-732
- Updated
- 2026-11-02
EUVDEUVD-2026-81591
10.0
vm2 versions from 3.11.3 before 3.11.7 expose the host tls module to NodeVM sandbox code, allowing attackers to call tls.setDefaultCACertificates() and replace process-wide certificate authorities. Attackers with access to allowed tls and url builtins can use URLSearchParams to create host-realm arrays and manipulate the TLS trust store, enabling subsequent host HTTPS clients to accept attacker-controlled certificates.
- Record
EUVD-2026-81591- CVSS 4.0
- 10.0 Critical
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:L/SC:H/SI:H/SA:L - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-98xx-8mx4-x7cm
10.0
vm2 NodeVM can replace the host process TLS trust store
Summary
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.
-
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.
-
In the attached
pocdirectory, run:npm install --ignore-scripts node poc.js -
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…
- Record
GHSA-98xx-8mx4-x7cm- CVSS 3.1
- 10.0 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:L - Weakness
- CWE-732
- Updated
- 2026-11-02
GitHub AdvisoriesGHSA-xq74-c7jx-8w5j
10.0
Duplicate Advisory: vm2 NodeVM can replace the host process TLS trust store
Duplicate Advisory
This advisory has been withdrawn because it is a duplicate of GHSA-98xx-8mx4-x7cm. This link is maintained to preserve external references.
Original Description
vm2 versions from 3.11.3 before 3.11.7 expose the host tls module to NodeVM sandbox code, allowing attackers to call tls.setDefaultCACertificates() and replace process-wide certificate authorities. Attackers with access to allowed tls and url builtins can use URLSearchParams to create host-realm arrays and manipulate the TLS trust store, enabling subsequent host HTTPS clients to accept attacker-controlled certificates.
- Record
GHSA-xq74-c7jx-8w5j- CVSS 4.0
- 10.0 Critical
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:L/SC:H/SI:H/SA:L/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - CVSS 3.1
- 10.0 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:L - Weakness
- CWE-732
- Updated
- 2026-11-02
NVD
10.0
vm2 versions from 3.11.3 before 3.11.7 expose the host tls module to NodeVM sandbox code, allowing attackers to call tls.setDefaultCACertificates() and replace process-wide certificate authorities. Attackers with access to allowed tls and url builtins can use URLSearchParams to create host-realm arrays and manipulate the TLS trust store, enabling subsequent host HTTPS clients to accept attacker-controlled certificates.
- Record
CVE-2026-92941- CVSS 4.0
- 10.0 Critical
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:L/SC:H/SI:H/SA:L/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - CVSS 3.1
- 10.0 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:L - Weakness
- CWE-732
- Updated
- 2026-11-02
OSV
10.0
vm2 3.11.3 before 3.11.7 TLS Trust Store Manipulation
vm2 versions from 3.11.3 before 3.11.7 expose the host tls module to NodeVM sandbox code, allowing attackers to call tls.setDefaultCACertificates() and replace process-wide certificate authorities. Attackers with access to allowed tls and url builtins can use URLSearchParams to create host-realm arrays and manipulate the TLS trust store, enabling subsequent host HTTPS clients to accept attacker-controlled certificates.
- Record
CVE-2026-92941- CVSS 4.0
- 10.0 Critical
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:L/SC:H/SI:H/SA:L - Weakness
- CWE-732
- Updated
- 2026-11-02
OSVGHSA-98xx-8mx4-x7cm
10.0
vm2 NodeVM can replace the host process TLS trust store
Summary
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.
-
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.
-
In the attached
pocdirectory, run:npm install --ignore-scripts node poc.js -
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…
- Record
GHSA-98xx-8mx4-x7cm- CVSS 3.1
- 10.0 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:L - Weakness
- CWE-732
- Updated
- 2026-11-02
OSVGHSA-xq74-c7jx-8w5j
10.0
Duplicate Advisory: vm2 NodeVM can replace the host process TLS trust store
Duplicate Advisory
This advisory has been withdrawn because it is a duplicate of GHSA-98xx-8mx4-x7cm. This link is maintained to preserve external references.
Original Description
vm2 versions from 3.11.3 before 3.11.7 expose the host tls module to NodeVM sandbox code, allowing attackers to call tls.setDefaultCACertificates() and replace process-wide certificate authorities. Attackers with access to allowed tls and url builtins can use URLSearchParams to create host-realm arrays and manipulate the TLS trust store, enabling subsequent host HTTPS clients to accept attacker-controlled certificates.
- Record
GHSA-xq74-c7jx-8w5j- CVSS 4.0
- 10.0 Critical
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:L/SC:H/SI:H/SA:L/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - CVSS 3.1
- 10.0 Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:L - Weakness
- CWE-732
- Updated
- 2026-11-02
OSVROOT-APP-NPM-CVE-2026-92941 No score
CVE-2026-92941 in vm2 - Patched by Root
Root has patched CVE-2026-92941 in the vm2 package for Root:npm. Multiple fixed versions available.
- Record
ROOT-APP-NPM-CVE-2026-92941- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
vm2npm |
3.11.3 to 3.11.6 | 3.11.7 |
vm2npm |
3.11.3 up to 3.11.7 | 3.11.7 |
vm2Root:npm |
before 3.11.6-aikido.1 | 3.11.6-aikido.1 |
@rootio/vm2Root:npm |
before 3.11.6-root.io.1 | 3.11.6-root.io.1 |
History
| Recorded | Changed | Sources |
|---|---|---|
| affected | ||
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-92941 is a critical vulnerability (CVSS 10.0) in Patriksimek Vm2, published September 17, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.29%, the 21st percentile. Fixed in vm2 3.11.7.
References
github.com/patriksimek/vm2/security/advisories/GHSA-98xx-8mx4-x7cm
vulncheck.com/advisories/vm2-3.11.3-before-3.11.7-tls-trust-store-manipulation
nvd.nist.gov/vuln/detail/CVE-2026-92941
github.com/patriksimek/vm2/commit/aa146a77f859325e079f3bfbfe6d8309af483daa
github.com/patriksimek/vm2/releases/tag/v3.11.7
github.com/advisories/GHSA-98xx-8mx4-x7cm
github.com/advisories/GHSA-xq74-c7jx-8w5j
github.com/CVEProject/cvelistV5/tree/main/cves/2026/92xxx/CVE-2026-92941.json
github.com/patriksimek/vm2
Left out here: the rest of 2 source descriptions. The JSON record has them.