Skip to content
Threat Feed
low advisory

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

  1. Attacker gains the ability to execute arbitrary code within a vm2 sandbox environment.
  2. Attacker identifies an exposed host-realm function (e.g., via sandbox configuration) that returns a Promise.
  3. Attacker invokes the host function to obtain a host-realm Promise instance.
  4. Alternatively, in NodeVM configurations, the attacker utilizes the events builtin to call events.once().
  5. Attacker triggers a rejection on the host-side object or event emitter.
  6. The bridge returns the rejected Promise to the sandbox without attaching a defensive .catch() or rejection handler.
  7. Attacker ignores the returned value, leaving the host Promise unhandled.
  8. 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 unhandledRejection handler in the host Node.js application to catch and swallow rejections originating from the vm2 sandbox, preventing process termination.
  • Audit all NodeVM configurations; disable the events builtin 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/promises uncaught exception errors to identify potential exploitation attempts.

Immediate actions

Deploy process-level unhandledRejection handler to suppress vm2-related crashes

Engineering 24h

Threat Hunt

Search application logs for 'node:internal/process/promises' and 'triggerUncaughtException' errors

T1059.003 high high confidence hunt now

Data: Node.js application logs

Mitigations

Remove 'events' builtin from all NodeVM configurations if not strictly required

immediate Engineering

NodeVM variant of the attack