vm2 Denial of Service via Host-Returned Promise Rejection
A vulnerability in the vm2 sandbox library (CVE-2026-92954) allows sandbox-based code to terminate the host Node.js process by invoking host-realm functions that return unhandled rejected Promises.
CVE search metadata
CVE search record: CVE-2026-92954. Severity: high. CVSS: 8.6. EPSS: 0.49%. KEV: no. Product: vm2 (3.10.0-3.11.7). Brief: vm2 Denial of Service via Host-Returned Promise Rejection. Brief link: https://feed.craftedsignal.io/briefs/2026-10-vm2-dos/
The vm2 sandbox library (versions 3.10.0 through 3.11.7) contains an incomplete fix for asynchronous rejection hardening, leading to a Denial of Service (DoS) vulnerability. When a sandbox executes code that calls a host-realm function returning a rejected Promise, the bridge mechanism fails to mark the host Promise as 'handled'. If the sandbox code does not explicitly attach a catch block to the returned Promise, the resulting unhandled rejection propagates to the host Node.js environment.
Node.js default behavior for unhandled rejections is to terminate the process, allowing an attacker to crash the entire application host. This vulnerability is particularly critical for multi-tenant environments, notebook workers, or plugin hosts that expose async host APIs or allow the 'events' builtin in NodeVM. This is a regression of hardening efforts originally introduced in GHSA-hw58-p9xv-2mjh and persists across major Node.js versions, including v16, v18, v20, v22, v24, and v25.
Attack Chain
- Attacker gains the ability to execute arbitrary code within a vm2 sandbox environment.
- Attacker identifies an exposed host-realm function (e.g., via
sandboxconfiguration) that returns a Promise. - Attacker invokes the host function to obtain a host-realm Promise instance.
- Alternatively, in
NodeVMconfigurations, the attacker utilizes theeventsbuiltin to callevents.once(). - Attacker triggers a rejection on the host-side object or event emitter.
- The bridge returns the rejected Promise to the sandbox without attaching a defensive
.catch()or rejection handler. - Attacker ignores the returned value, leaving the host Promise unhandled.
- The host Node.js runtime detects the unhandled rejection and terminates the parent process, causing a DoS.
Impact
Successful exploitation results in the immediate termination of the host Node.js process. This impacts any multi-tenant system, web service, or background worker utilizing vm2 for code isolation. Because the payload can be replayed after a process restart, automated recovery policies are ineffective against this primitive.
Recommendation
Immediate mitigation is required for all applications using vm2.
- Implement a process-level
unhandledRejectionhandler in the host Node.js application to catch and swallow rejections originating from the vm2 sandbox, preventing process termination. - Audit all
NodeVMconfigurations; disable theeventsbuiltin if it is not strictly required for sandbox functionality. - Restrict the exposure of host-realm functions that return Promises to sandboxed environments.
- Monitor logs for the
node:internal/process/promisesuncaught exception errors to identify potential exploitation attempts.
Immediate actions
Deploy process-level unhandledRejection handler to suppress vm2-related crashes
Threat Hunt
Search application logs for 'node:internal/process/promises' and 'triggerUncaughtException' errors
Data: Node.js application logs
Mitigations
Remove 'events' builtin from all NodeVM configurations if not strictly required
NodeVM variant of the attack