Executive brief
VM2 is a popular Node.js library used to safely execute untrusted code in an isolated sandbox environment. An attacker can exploit a flaw in how the library handles Promise rejection errors to break out of the sandbox and execute arbitrary system commands with the privileges of the host process, completely bypassing the sandbox protection.
Technical details
The vulnerability exists in VM2's promise handling at the host-sandbox boundary. When an embedder exposes a host-realm async function to sandboxed code via the sandbox options, the bridge returns a host-realm Promise wrapped as a proxy. However, when the sandbox calls `.then()`, `.catch()`, or `.finally()` on this proxy, the promise chain invokes callbacks against raw host rejection values, bypassing the sandbox's `handleException` sanitization layer. This allows a SuppressedError thrown in the host realm to reach the sandbox catch handler unsanitized. An attacker can then access the error's `.constructor.constructor` property chain to obtain the host Function constructor, enabling arbitrary code execution via eval-like patterns. The vulnerability affects VM2 versions ≤ 3.10.4 and requires no authentication or user interaction; exploitation is triggered by sandboxed code alone. A patch is available in v3.11.0 which enforces structural sanitization at the host-Promise boundary by wrapping all callbacks through sandbox-side sanitizing closures.
Affected products
- patriksimek vm2 <= 3.10.4
Timeline
- 2026-05-05: disclosed
- 2026-05-01: patched: Fix released in v3.11.0
References
- https://github.com/patriksimek/vm2/security/advisories/GHSA-55hx-c926-fr95
- https://github.com/patriksimek/vm2/commit/119fd0aa1e4c27b08cf37946b2dafa99e2c754f0
- https://github.com/patriksimek/vm2/commit/4cb82cc94d9bb6c9a918b45f8c6790c32a5e913f
- https://github.com/patriksimek/vm2/commit/7395c3a4b01d302e55271c87dbeb44d6b83b81ca
- https://github.com/patriksimek/vm2/commit/792e16d56ee429ab19e284ed9c545f5e4694fb7d
- https://github.com/patriksimek/vm2/commit/d715dd88c5aec5bbb4dce03ddf7c3eb3791d0338