The vulnerability in vm2 (GHSA-m5q2-4fm3-vfqp) is a sandbox escape caused by a combination of two main weaknesses. First, the sandbox's override of the global Symbol.for function was incomplete. It only blocked two of nine known dangerous Node.js internal symbols. This allowed sandboxed code to create and get references to real cross-realm symbols (e.g., nodejs.util.promisify.custom) that Node.js internals use for special hooks. Second, the proxy-based bridge that separates the sandbox from the host environment had a critical flaw in its write-trap handlers (set, defineProperty, deleteProperty). These traps, which handle property modifications on host objects, failed to check if the property key being used was one of these dangerous symbols.
An attacker could exploit this by first using the flawed Symbol.for to obtain a real dangerous symbol. Then, they could use this symbol as a property key in an assignment (=), Object.defineProperty, or delete operation on a host object exposed to the sandbox. This would allow the attacker to install a custom function (a hook) or modify the behavior of the host object. For example, by setting a custom nodejs.util.promisify.custom function on a host function, the attacker could control the result of util.promisify on the host side, leading to data integrity issues and allowing the sandbox to influence host-side control flow. The patch addresses this with a two-layer fix: it blocks the entire nodejs.* namespace in Symbol.for and adds the missing security checks to the bridge's write traps.