CVE-2026-92959
HighCVSS 7.1Summary
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, allowing sandboxed script to schedule work that runs after VM.run() or NodeVM.run() has returned and outside the configured timeout.
Risk Assessment
Sandboxed code can continue executing after the host believes execution is complete, potentially leading to unexpected actions and bypassing timeout restrictions. This can undermine sandbox isolation.
Recommendation
Upgrade vm2 to version 3.11.8 or later. Do not rely solely on the allowAsync: false option to restrict asynchronicity in untrusted code.
Other vulnerabilities in vm2
See all- CVE-2026-92963Medium
vm2 versions before 3.11.2 fail to properly restrict access to the VM2_INTERNAL_STATE_DO_NOT_USE_OR_PROGRAM_WILL_FAIL global variable. Attackers can access this internal state object through globalThis to retrieve sensitive sandbox internals.
- CVE-2026-92962Low
vm2, a sandbox for running untrusted JavaScript, in versions up to and including 3.11.3 uses prototype-walking index assignment in defaultSandboxPrepareStackTrace, allowing sandbox code to intercept error stack lines. The impact is low (information side channel) and the issue is fixed in version 3.11.4.
- CVE-2026-92961High
vm2 before 3.11.6 fails to enforce bufferAllocLimit on ArrayBuffer, SharedArrayBuffer, and TypedArray constructors, allowing attackers to allocate arbitrary host memory. Attackers can bypass the buffer allocation cap by using these V8 intrinsics to exhaust host process memory and trigger out-of-memory conditions.
- CVE-2026-92958High
vm2 through 3.11.6 contains a builtin-module denylist bypass in NodeVM. When the embedder uses the builtin wildcard together with negative entries (e.g. require: { builtin: ['*', '-fs', '-child_process'] }), negative entries are matched by exact module name, so -fs removes only the builtin named fs and does not remove builtin subpaths such as fs/promises. Sandboxed code can therefore call require('fs/promises') or require('node:fs/promises') and reach the promise-based filesystem API despite fs being denied.
- CVE-2026-92954High
vm2 versions >= 3.10.0 and <= 3.11.7 do not mark Promises returned from the host realm into the sandbox as handled at the bridge boundary. Only Promises created inside the sandbox are wrapped with a rejection-swallowing handler, and the bridge only installs host-side rejection sanitizers when sandbox code calls .then/.catch/.finally. As a result, sandboxed code can invoke a host function that returns a rejected Promise and ignore the return value, leaving the host Promise unhandled so that Node.js's default unhandled-rejection behavior terminates the host process.
- CVE-2026-92952Medium
vm2 versions 3.11.4 through 3.11.6 incompletely filter Node.js registered internal symbols across the sandbox boundary. The extraction filters in lib/setup-sandbox.js and the cross-realm symbol checks and write traps in lib/bridge.js use a fixed list of known dangerous registered symbols that omits nodejs.stream.disturbed and nodejs.stream.errored, which are exposed on host WebStream prototypes on newer Node.js releases. When the embedder exposes a host WebStream object and the host stream/web module to the sandbox, sandbox code can obtain the real host symbols and use them as write keys on host stream objects, corrupting host-visible stream state. This can bypass host logic that relies on Node's public stream-state helpers. It is not a host code-execution primitive in the reported proof of vulnerability. This is an incomplete fix for the earlier nodejs.* symbol filtering issue. Fixed in vm2 3.11.7.
- CVE-2026-92950High
A vulnerability in the vm2 CLI tool (before 3.11.7) allows sandbox escape and arbitrary code execution in the host Node.js process. Attackers can supply a malicious script that uses require(__filename) to re-execute itself in the host realm, bypassing sandbox isolation and accessing host modules like fs and child_process.
- CVE-2026-92949Medium
vm2 versions from 3.9.6 before 3.11.7 fail to properly restrict access to accessor properties on frozen objects, allowing sandboxed scripts to bypass vm.freeze() and vm.readonly() protections. Attackers can use Object.getOwnPropertyDescriptor() or __lookupSetter__() to extract and invoke host object setters directly, mutating properties the embedder explicitly marked read-only.
- CVE-2026-92945Medium
vm2 before 3.11.7 contains a module allowlist bypass vulnerability in isPathAllowedForModule that uses raw string prefix matching instead of boundary-anchored comparison. Attackers can reach non-allowlisted packages sharing a prefix with allowlisted modules by performing relative requires from allowlisted packages when transitive loading is disabled.
- CVE-2026-92942High
In vm2 versions ≤ 3.11.6, the VM({ timeout }) option is not enforced for code executed outside the synchronous VM#run() call. Sandboxed code can register a FinalizationRegistry callback and, after dropping an object reference, block the host event loop indefinitely, causing denial of service.
Original NVD description (English source)
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.

