Improper authorization control for web services In vm2
Description
vm2: Sandbox Escape (NodeVM)
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
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] {} ...
Mitigation
Update Impact
Minimal update. May introduce new vulnerabilities or breaking changes.
Ecosystem | Component | Affected version | Patched versions |
|---|---|---|---|
npm | 3.11.8 |
Aliases
References