# Sandbox allowlist gaps miss sibling paths

Hand-enumerated guards (intrinsics, coders, Proxy traps) that omit sibling paths to host state

_Area: Memory corruption and native code. Seen in 3 disclosed reports; one confirmed bounty: $2,430; latest 2026-10-05. Updated 2026-11-08._

## How it works
A sandbox protects host state by naming what it guards: a list of intrinsics, a list of blocked coders, a set of Proxy traps. The assumption that breaks is that the list is complete. Anything reachable that is not on the list — a sibling intrinsic family, another coder calling the same delegate, a prototype-inherited write — still reaches host state. The guard is only as strong as its enumeration, and hand-maintained enumerations drift from the real surface.

## Where it shows up
- A fixed `globalsList` of protected intrinsics naming classic constructors but omitting `%TypedArray%` concrete prototypes, `ArrayBuffer`, `SharedArrayBuffer`, `DataView` [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-3vgf-8m4q-q4qr.md)
- Sanitize-then-re-encode flows where the re-encode calls a user-replaceable prototype method (`Buffer.from` → `utf8Write`) [E1](https://bugbountylibrary.com/r/h1%3A2434811.md)
- Proxy traps that accept `receiver` but never use it, writing to the host target unconditionally [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-c4cf-2hgv-2qv6.md)
- Bridge `defineProperty` writes that reach host prototypes through a prototype chain not on the protected list [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-3vgf-8m4q-q4qr.md)

## How to review
For each guard, ask: what is the full set of things that can reach this state, and does the guard cover all of them?
- Intrinsic guards: enumerate every intrinsic family (all typed-array prototypes, buffers, DataView) and confirm each is protected, not just the named list [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-3vgf-8m4q-q4qr.md).
- Sanitization: the invariant is that the value validated is the value used. Any conversion after validation must not route through a replaceable prototype method [E1](https://bugbountylibrary.com/r/h1%3A2434811.md).
- Proxy traps: `set` must honor `receiver`; a write on a prototype-inheriting child must create an own property on the child, not leak to the host target [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-c4cf-2hgv-2qv6.md).

## How finders spotted it
- Treated a prior fix as a coverage problem: saw the protected inventory was a hand-maintained `globalsList`, checked which intrinsic families were missing, and reused the existing host-prototype walking primitive to reach them [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-3vgf-8m4q-q4qr.md).
- Reasoned that a prior patch replaced `Buffer.from` but left its internal `utf8Write` call monkey-patchable, giving a hook after sanitization [E1](https://bugbountylibrary.com/r/h1%3A2434811.md).
- Read the Proxy `set` trap against the spec, noticed `receiver` was accepted but unused, and that the reflect-set always targeted the host object [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-c4cf-2hgv-2qv6.md).

## Variants seen
- Missing intrinsic family in a fixed globals list [E2](https://bugbountylibrary.com/r/ghsa%3AGHSA-3vgf-8m4q-q4qr.md)
- Post-validation re-encode through a replaceable prototype method [E1](https://bugbountylibrary.com/r/h1%3A2434811.md)
- Proxy trap ignoring `receiver`, leaking inherited writes to host [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-c4cf-2hgv-2qv6.md)

## Impact and severity
E1 bypassed the Node.js permission model to read files outside the allowed directory. E2 gave sandbox code write primitives onto host typed-array and ArrayBuffer intrinsics, enabling host-side behavior hijack. E3 leaked inherited writes onto host objects, hijacking `util.promisify` behavior, and chains with a separate symbol coverage gap to bypass a future cross-realm symbol guard [E3](https://bugbountylibrary.com/r/ghsa%3AGHSA-c4cf-2hgv-2qv6.md). Severity rises with how far the reached state extends: host intrinsics and delegates scale to RCE, single-file reads stay lower.

## Seen in real software
Open-source packages and projects, and products, where this pattern was found. If the target runs one, compare the version it runs with the fix.
- **vm2 (npm)** >= 3.11.0, <= 3.11.7, fixed in 3.11.8: vm2: Default VM can mutate host TypedArray and ArrayBuffer intrinsics after the host-prototype pollution fix (CVE-2026-92953). Report: https://bugbountylibrary.com/r/ghsa%3AGHSA-3vgf-8m4q-q4qr.md. Fix: https://github.com/patriksimek/vm2/commit/92a10fca7b3ca63bb1574b6795540264f6805b30
- **vm2 (npm)** <= 3.11.3, fixed in 3.11.4: vm2's Bridge Proxy set trap ignores receiver parameter, enabling host object property injection via prototype chain (CVE-2026-47209). Report: https://bugbountylibrary.com/r/ghsa%3AGHSA-c4cf-2hgv-2qv6.md. Fix: https://github.com/patriksimek/vm2/commit/26d0318b5e6555be4b187ba05d6cf378ccecfe22
- **Node.js**: Path traversal by monkey-patching Buffer internals (CVE-2024-21896). Report: https://bugbountylibrary.com/r/h1%3A2434811.md. Fix: https://github.com/nodejs/node/commit/1f64147eb607f82060e08884f993597774c69280

## Evidence
- E1: https://bugbountylibrary.com/r/h1%3A2434811.md
- E2: https://bugbountylibrary.com/r/ghsa%3AGHSA-3vgf-8m4q-q4qr.md
- E3: https://bugbountylibrary.com/r/ghsa%3AGHSA-c4cf-2hgv-2qv6.md
