CVE-2026-92959
### Summary When `allowAsync` is set to `false`, vm2 is expected to reject attempts to run asynchronous code. Direct use of `Promise.prototype.then` is blocked, but Promise static methods still assimilate attacker-controlled thenables. `Promise.resolve(thenable)`, `Promise.all([thenable])`, `Promise.race([thenable])`, `Promise.any([thenable])`, and `Promise.allSettled([thenable])` can invoke the thenable's `then` method in a microtask after `VM.run()` or `NodeVM.run()` has already returned. This bypasses the documented async-execution restriction and runs outside the configured `timeout`, allowing sandboxed code to continue executing after the host believes execution is complete. ### Details The documented VM option says `allowAsync: false` should cause attempts to run async code to throw a `VMError`; README.md:139-145 also recommends using it with `timeout`. The implementation enforces part of this policy by replacing `localPromise.prototype.then` with an `AsyncErrorHandler` when async is disabled: - `lib/setup-sandbox.js:1629-1637` defines `AsyncErrorHandler`, whose `apply` and `construct` traps throw `VMError: Async not available`. - `lib/setup-sandbox.js:1743-1752` installs that handler on `localPromise.prototype.then` when `allowAsync` is false. However, Promise static methods are still exposed and rebound to `localPromise`: - `lib/setup-sandbox.js:1816-1819` wraps `Promise.all`. - `lib/setup-sandbox.js:1821-1824` wraps `Promise.race`. - `lib/setup-sandbox.js:1826-1830` wraps `Promise.allSettled`. - `lib/setup-sandbox.js:1833-1837` wraps `Promise.any`. - `lib/setup-sandbox.js:1840-1843` wraps `Promise.resolve`. Those wrappers prevent species attacks by forcing `localPromise` as the constructor, but they do not reject or neutralize thenables when `allowAsync` is false. Native Promise resolution then performs `PromiseResolveThenableJob` and calls the attacker-controlled `then` method asynchronously. That job does not go through the patched `localPromise.p
Properties
- severity
- high
- summary
- vm2: `allowAsync: false` can be bypassed through Promise thenable assimilation in VM and NodeVM
- epss_score
- 0.00449
- cvss_score
- 7.1
- retrieved_at
- 2026-10-05T22:59:58+00:00
- ghsa_published
- 2026-10-05T22:47:34Z
- source_url
- https://github.com/advisories/GHSA-f8gf-w286-fmq2
- ghsa_updated
- 2026-10-05T22:47:35Z
- ghsa_id
- GHSA-f8gf-w286-fmq2
- last_source
- FIRST EPSS
- cve_id
- CVE-2026-92959
- cvss_vector
- CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:H
- signal_observed_at
- 2026-10-05T22:52:21+00:00
- is_ghsa_only
- false
- epss_percentile
- 0.36785
Related Entities (5)
ENRICHED_BY (1)
VULNERABLE_TO (1)
AFFECTS (1)
HAS_WEAKNESS (1)
REPORTED_BY (1)
Explore deeper with Ninja Signal's threat intelligence graph