The vulnerability is a sandbox escape in vm2 caused by the incomplete setup of the sandboxed environment. The root cause is the failure to remove two powerful, host-provided functions, WebAssembly.promising and WebAssembly.Suspending, from the global scope of the sandbox. These functions are part of the experimental WebAssembly JavaScript Promise Integration (JSPI) API.
The VM.constructor is the function responsible for creating the sandbox. It was vulnerable because it did not blacklist these functions, leaving them accessible to any code executed within the sandbox. An attacker can craft JavaScript code that uses these functions to create a special type of Promise. This Promise's prototype chain links directly to the host's Promise.prototype, bypassing all of vm2's proxy-based security wrappers and Promise-related hardening.
The VM.run method is the function that executes this malicious code inside the improperly configured sandbox. When the specially crafted Promise rejects, it does so with an error object originating from the host environment. Because the security wrappers were bypassed, the attacker's code receives the raw host error object, allowing it to access its constructor (Function) and ultimately the host's process object, leading to arbitrary code execution on the host machine.
The patch addresses the vulnerability by modifying the sandbox setup script (lib/setup-sandbox.js), which is executed during the VM's construction. It adds logic to explicitly delete WebAssembly.promising and WebAssembly.Suspending from the WebAssembly object within the sandbox, thus closing the hole.