Executive brief
vm2 is a popular Node.js library that runs untrusted JavaScript in a sandboxed environment. A flaw in how it handles rejected Promises allows attackers to bypass the sandbox and execute arbitrary system commands with the privileges of the host Node.js process. This affects any application that exposes async operations to sandboxed code and could lead to complete system compromise.
Technical details
The vulnerability is a sandbox escape in vm2's Promise rejection handler sanitisation logic. The bridge sanitiser at lib/bridge.js:1624 uses identity checks to determine whether to rebuild rejected Promise values before passing them to sandbox callbacks. However, when rejection handlers are registered via Function.prototype.call or .apply indirection (e.g., p.then.call(p, undefined, cb)), the intercepted target becomes the host Function.prototype.call itself rather than the Promise, bypassing the sanitiser. This allows raw host error objects with non-primitive own properties (e.g., err.detail = process) to reach sandbox code as fully functional proxies. No authentication or special privileges are required; the attacker need only submit malicious code to be evaluated. The fix is available in vm2 3.11.7, which properly sanitises all rejection paths.
Affected products
- patriksimek vm2 3.11.6
Timeline
- 2026-09-17: disclosed
- 2026-08-24: patched: Fix released in version 3.11.7