Assumed repo path is /Users/zwique/Downloads/SandboxJS-0.8.34 (no /Users/zwique/Downloads/SandboxJS found). A global tick state (currentTicks.current) is shared between sandboxes. Timer string handlers are compiled at execution time using that global tick state rather than the scheduling sandbox's tick object. In multi-tenant / concurrent sandbox scenarios, another sandbox can overwrite currentTicks.current between scheduling and execution, causing the timer callback to run under a different sandbox's tick budget and bypass the original sandbox's execution …
It is possible to obtain arrays containing Function, which allows escaping the sandbox.
A sandbox escape vulnerability allows sandboxed code to mutate host built-in prototypes by laundering the isGlobal protection flag through array literal intermediaries. When a global prototype reference (e.g., Map.prototype, Set.prototype) is placed into an array and retrieved, the isGlobal taint is stripped, permitting direct prototype mutation from within the sandbox. This results in persistent host-side prototype pollution and may enable RCE in applications that use polluted properties in sensitive sinks …
A sandbox escape vulnerabilities due to a mismatch between the key on which the validation is performed and the key used for accessing properties.
A sandbox escape is possible by shadowing hasOwnProperty on a sandbox object, which disables prototype whitelist enforcement in the property-access path. This permits direct access to proto and other blocked prototype properties, enabling host Object.prototype pollution and persistent cross-sandbox impact. The issue was reproducible on Node v23.9.0 using the project’s current build output. The bypass works with default Sandbox configuration and does not require custom globals or whitelists.
As Map is in SAFE_PROTOYPES, it's prototype can be obtained via Map.prototype. By overwriting Map.prototype.has the sandbox can be escaped.
The return values of functions aren't wrapped. Object.values/Object.entries can be used to get an Array containing the host's Function constructor, by using Array.prototype.at you can obtain the hosts Function constructor, which can be used to execute arbitrary code outside of the sandbox.
SandboxJS does not properly restrict lookupGetter which can be used to obtain prototypes, which can be used for escaping the sandbox / remote code execution.
A sandbox escape vulnerability due to AsyncFunction not being isolated in SandboxFunction