The vulnerability is a sandbox escape in enclave-vm triggered by executing specially crafted JavaScript code via the Enclave.run method. The root cause is a combination of two weaknesses:
-
Insufficient AST Sanitization: The static analysis of the code, performed by rules like ResourceExhaustionRule, could be bypassed. An attacker could use dynamic property access with string coercion (e.g., error[String(['__proto__'])]) to hide access to sensitive properties like __proto__ and constructor. The ResourceExhaustionRule.MemberExpression function, which is responsible for checking property access, did not account for these dynamic patterns, allowing the malicious payload to pass the sanitization step.
-
Leaked Host References from Error Objects: Once the malicious code bypassed validation and was executed, it would trigger an infinite recursion, causing a stack overflow and generating a RangeError. Due to a weakness in how the underlying Node.js vm module handles such errors, the thrown RangeError object retained a prototype chain that led back to the host environment's Object.prototype. The sandbox environment was not sufficiently hardened to sever this chain.
The exploit involves catching this error, traversing its prototype chain (e.g., e.__proto__.__proto__.__proto__) to get a reference to the host's Object.prototype, and then accessing the Function constructor to execute arbitrary code with the privileges of the host process.
The patch addresses this by enhancing the AST validation in ResourceExhaustionRule to detect and block these dynamic property access patterns, and by adding hardening measures in the VM bootstrap script (parent-vm-bootstrap.ts) to shadow the __proto__ property on all Error prototypes, effectively cutting off the prototype chain traversal attack.