# Sandbox require config bypass

Check sandbox require/import config defaults, prefix normalization, array shapes, and unanchored allowlists

_Area: Web injection and code execution. Seen in 6 disclosed reports; latest 2026-10-05. Updated 2026-10-23._

## How it works
A sandboxed runtime decides what code may load via a require/import policy. The policy is only as strong as its config parsing and comparison logic. The assumption that breaks: that a configured guard is actually enforcing. Defaults can be no-ops (undefined root means "allow all"), comparisons can be looser than the specifier space (substring vs exact), normalization can differ between the check and the load, and shape checks can accept unintended types. Any of these lets sandboxed code reach host modules and host execution.

## Where it shows up
- Resolver where an undefined/absent root path short-circuits to "allowed" [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-j3hm-6rg5-mchv.md)[E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-jxxv-8r27-vm4p.md)
- Context defaulting to host realm, so loads route through the real host require [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-j3hm-6rg5-mchv.md)[E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-jxxv-8r27-vm4p.md)
- Allowlists matched by unanchored regex or substring rather than exact package name [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-c48m-32m9-vx93.md)
- Specifier canonicalization (e.g. `node:` prefix stripping) applied in one path but not the deny comparison [E4](https://bugbountylibrary.com/r/ghsa%3AGHSA-8686-vhfx-7r3j.md)
- Config guards using `typeof x === 'object'` that accept arrays or other exotic shapes [E5](https://bugbountylibrary.com/r/ghsa%3AGHSA-8hr7-r645-pc6w.md)
- The sandbox's own package reachable from the allowed root, yielding unwrapped host classes [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-j3hm-6rg5-mchv.md)
- CLI wrappers that omit root/context/builtin options [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-jxxv-8r27-vm4p.md)

## How to review
For each require/import decision, trace the exact value compared at the check and at the load. The invariant: the set of specifiers that pass the guard must equal the set the loader will resolve, and no default may widen it. Verify: (1) absent root/context fails closed, not open; (2) allow/deny comparisons are exact or fully anchored, on the same normalized form used at load; (3) shape validation rejects arrays and non-plain objects; (4) the sandbox package itself is not reachable from the allowed root; (5) host-realm loading is never used for sandbox-originated requests.

## Variants seen
- Undefined rootPaths makes isPathAllowed always true; host context loads real require [E1](https://bugbountylibrary.com/r/ghsa%3AGHSA-j3hm-6rg5-mchv.md)
- CLI passes external:true with no root/context, same fail-open [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-jxxv-8r27-vm4p.md)
- Unanchored allowlist regex substring-matches colliding package names [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-c48m-32m9-vx93.md)
- `node:` prefix stripped before load but deny-list matched exactly, so `-node:child_process` misses [E4](https://bugbountylibrary.com/r/ghsa%3AGHSA-8686-vhfx-7r3j.md)
- Array-shaped `require: []` passes object guard, producing degenerate resolver [E5](https://bugbountylibrary.com/r/ghsa%3AGHSA-8hr7-r645-pc6w.md)

## Impact and severity
All five led to host RCE from sandboxed code. Severity is critical: the sandbox is the only boundary, and each bypass defeats it entirely. Worse when the sandbox package is reachable from the allowed root, since it yields unwrapped host primitives.

## Evidence
- E1: https://bugbountylibrary.com/r/ghsa%3AGHSA-j3hm-6rg5-mchv.md
- E2: https://bugbountylibrary.com/r/ghsa%3AGHSA-jxxv-8r27-vm4p.md
- E3: https://bugbountylibrary.com/r/ghsa%3AGHSA-c48m-32m9-vx93.md
- E4: https://bugbountylibrary.com/r/ghsa%3AGHSA-8686-vhfx-7r3j.md
- E5: https://bugbountylibrary.com/r/ghsa%3AGHSA-8hr7-r645-pc6w.md
