CVE-2026-92959: vm2 before 3.11.8 allowAsync Bypass via Promise Thenable
vm2 before 3.11.8 does not fully enforce the allowAsync: false option in VM and NodeVM. While localPromise.prototype.then is replaced with a handler that throws 'Async not available', the sandbox's Promise static methods (Promise.resolve, Promise.all, Promise.race, Promise.any, and Promise.allSettled) still assimilate attacker-supplied thenables: native promise resolution performs PromiseResolveThenableJob and invokes the sandboxed code's then method in a microtask without passing through the patched then, so the async restriction is never applied. As a result, sandboxed script can schedule work that runs after VM.run() or NodeVM.run() has returned and outside the configured timeout, continuing to execute after the host believes execution is complete.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
vm2to a version that resolves this vulnerability.Fixed in 3.11.8Patch vm2 before 3.11.8 allowAsync Bypass via Promise Thenable - Configuration
Ensure allowAsync is set to false in the VM/NodeVM options; vm2 before 3.11.8 does not fully enforce allowAsync: false, allowing bypass via Promise thenables.
vm2 (VM/NodeVM option allowAsync) allowAsync = false
Event History
Frequently Asked Questions
Who is exposed to this issue?
Applications using npm/vm2 before 3.11.8 are exposed when they run untrusted sandboxed code in VM or NodeVM with allowAsync set to false. The issue matters where the host relies on that setting or the configured timeout to ensure sandboxed execution has finished.
What does an attacker need to exploit it?
An attacker needs the ability to supply or control JavaScript executed inside the vm2 sandbox. They can provide a thenable whose then method is assimilated through Promise static methods such as Promise.resolve, Promise.all, Promise.race, Promise.any, or Promise.allSettled.
What is the impact of a successful exploit?
Sandboxed code can schedule microtask work that executes after VM.run() or NodeVM.run() returns. This work runs outside the configured timeout, so the host may treat execution as complete while attacker-controlled sandbox code continues running.
What should be done if upgrading is not immediately possible?
Do not rely on allowAsync: false or the configured timeout as a complete execution boundary for untrusted code. Avoid running untrusted sandboxed scripts that can use Promise static methods with attacker-controlled thenables until vm2 is updated to 3.11.8 or later.