# Sandbox escape via constructor and coercion chains

Sandboxed user code reaching Function/eval through constructor, toString, or property coercion gadgets

_Area: Web injection and code execution. Seen in 3 disclosed reports; latest 2026-08-04. Updated 2026-10-27._

## How it works
A sandbox assumes untrusted code cannot reach the host's real `Function`/`eval`. That assumption breaks whenever the sandboxed code can obtain any host object and walk a chain: `obj.constructor.constructor` yields `Function`, and implicit coercion (`toString`/`valueOf`) or a patched library method can invoke attacker-chosen host functions. The boundary is only as strong as the object graph exposed inside it.

## Where it shows up
- `node:vm` / `vm.runInContext` / `runInNewContext` used as a security boundary on user-supplied code [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-v264-xqh4-9xmm.md)
- Deprecated `vm2` still wired into nodes, or nodes passing `useSandbox:false` [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-wg86-r78f-74mp.md)
- User input string-interpolated into generated sandboxed JS after only a weak validator (e.g. `new URL()`, which ignores the hash fragment) [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-wg86-r78f-74mp.md)
- Sandboxed libraries with patched methods that call attacker-controlled methods (e.g. `name.match()` in a locale path-traversal patch) [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-wg86-r78f-74mp.md)
- Expression evaluators allowing member access to `window`/globals, where a global function can serve as a `toString`/`valueOf` gadget [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-7f2v-3qq3-vvjf.md)
- Custom-code runners executing in the same process as a privileged worker (host networking, secrets in env) [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-v264-xqh4-9xmm.md)

## How to review
Identify every path where untrusted code or strings enter an interpreter. The invariant: untrusted code must run in a true isolation boundary (separate process/container without secrets or host network), and no host object reachable inside the sandbox may expose `constructor`/`Function`/`eval`. Check that validators reject the whole input (including fragments), that interpolated values are escaped or passed as data not code, and that patched library methods do not call methods on attacker-controlled objects. For expression engines, confirm globals are not member-accessible and coercion hooks cannot reach host functions.

## Variants seen
- Weak URL validation plus string interpolation into sandboxed JS, bypassing a patched library method via overridden `match()` [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-wg86-r78f-74mp.md)
- `node:vm` treated as a boundary; escape via constructor chain to RCE on a host-networked probe [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-v264-xqh4-9xmm.md)
- Expression sandbox with `window` member access; `toString` gadget on a global reaching `eval`, yielding DOM XSS [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-7f2v-3qq3-vvjf.md)

## Impact and severity
All three reached code execution or script execution: RCE on the host/probe with credential theft [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-wg86-r78f-74mp.md)[E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-v264-xqh4-9xmm.md), and DOM XSS [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-7f2v-3qq3-vvjf.md). Severity was raised by same-process privileged execution, host networking, and secrets in environment variables [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-v264-xqh4-9xmm.md), and by authenticated-but-low-privilege access being sufficient [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-wg86-r78f-74mp.md)[E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-v264-xqh4-9xmm.md).

## Evidence
- E1: https://bugbountylibrary.com/r/ghsa%3AGHSA-wg86-r78f-74mp.md
- E2: https://bugbountylibrary.com/r/ghsa%3AGHSA-v264-xqh4-9xmm.md
- E3: https://bugbountylibrary.com/r/ghsa%3AGHSA-7f2v-3qq3-vvjf.md
