# Sandbox allowlist broader than intended operation

Allowlisted service, module or hook that grants more capability than the one operation it was meant for

_Area: Memory corruption and native code. Seen in 3 disclosed reports; latest 2026-10-30. Updated 2026-11-02._

## How it works
A sandbox or injection filter decides access by a coarse key: a service name, a DLL filename, a hook API. The designer assumes "allow this key" equals "allow this one operation." That assumption breaks because the key unlocks the whole client API behind it, or matches any file with that name. The gate checks identity, not what the caller then does with it [E2](https://bugbountylibrary.com/r/blog%3Apwn-ai-blog-chrome-escape.md)[E3](https://bugbountylibrary.com/r/h1%3A870615.md). In Electron, the same shape appears as a missing `sandbox: true` while `nodeIntegration` is off and `contextIsolation` is on: the profile looks locked down but one window path runs unsandboxed [E1](https://bugbountylibrary.com/r/blog%3Ablog-electrovolt-io-posts-discord-rce.md).

## Where it shows up
- Seatbelt/macOS profiles with `mach-lookup` exceptions for graphics services (e.g. WindowServer) [E2](https://bugbountylibrary.com/r/blog%3Apwn-ai-blog-chrome-escape.md)
- Electron `webPreferences` missing `sandbox: true`, especially on embed/preview/new-window renderers [E1](https://bugbountylibrary.com/r/blog%3Ablog-electrovolt-io-posts-discord-rce.md)
- New-window handlers that check the opener but not post-redirect origin [E1](https://bugbountylibrary.com/r/blog%3Ablog-electrovolt-io-posts-discord-rce.md)
- Injection filters that allowlist by DLL filename (e.g. `tiptsf.dll`) rather than by signer/path [E3](https://bugbountylibrary.com/r/h1%3A870615.md)
- Any allowlist entry whose comment says "needed for X" but whose API surface is much larger than X [E2](https://bugbountylibrary.com/r/blog%3Apwn-ai-blog-chrome-escape.md)

## How to review
For each allowlist entry, name the single operation it exists for, then enumerate what the granted handle actually exposes. The invariant: the capability reachable after the check must be no broader than the intended operation. For Mach services, list the private framework exports (`.tbd` stubs) reachable once connected and confirm none post events or authorize actions [E2](https://bugbountylibrary.com/r/blog%3Apwn-ai-blog-chrome-escape.md). For Electron, confirm `sandbox: true` on every window, including embed and new-window paths, and that redirects cannot clear it [E1](https://bugbountylibrary.com/r/blog%3Ablog-electrovolt-io-posts-discord-rce.md). For filename allowlists, require signer or full-path checks, not basename matching [E3](https://bugbountylibrary.com/r/h1%3A870615.md).

## How finders spotted it
- Extracted the asar, read `webPreferences`, saw `nodeIntegration` off and `contextIsolation` on but `sandbox` absent, plus an old Chromium; pivoted from the React frontend to embed renderers, and a teammate flagged the new-window restriction as insufficient, then observed a cross-origin redirect clearing the sandbox [E1](https://bugbountylibrary.com/r/blog%3Ablog-electrovolt-io-posts-discord-rce.md)
- Noticed the WindowServer mach-lookup exception in the GPU Seatbelt profile and reasoned Seatbelt gates only the lookup, not post-connection operations; then mined `.tbd` stub exports for private event-posting symbols and tested them inside the live sandbox [E2](https://bugbountylibrary.com/r/blog%3Apwn-ai-blog-chrome-escape.md)
- Saw the ClientLoadLibrary hook blocked injection generally but specific DLL names like `tiptsf.dll` slipped through, then explored GUI message APIs to bypass the confirmation dialog [E3](https://bugbountylibrary.com/r/h1%3A870615.md)

## Variants seen
- Service allowlist exposing full client API (WindowServer keystroke injection) [E2](https://bugbountylibrary.com/r/blog%3Apwn-ai-blog-chrome-escape.md)
- Missing sandbox flag on one window class in an otherwise hardened Electron app [E1](https://bugbountylibrary.com/r/blog%3Ablog-electrovolt-io-posts-discord-rce.md)
- Filename-based injection allowlist bypassed by a system DLL name [E3](https://bugbountylibrary.com/r/h1%3A870615.md)

## Impact and severity
Each case turned a limited foothold into full control: GPU-process compromise to desktop keystroke injection and app launch [E2](https://bugbountylibrary.com/r/blog%3Apwn-ai-blog-chrome-escape.md); embed XSS to unsandboxed window to V8 exploit and RCE [E1](https://bugbountylibrary.com/r/blog%3Ablog-electrovolt-io-posts-discord-rce.md); unprivileged DLL injection to disabling antivirus, enabling ransomware [E3](https://bugbountylibrary.com/r/h1%3A870615.md). Severity is raised by chaining with a second weakness (XSS, GUI dialog auto-approval) and by the allowlist reaching a privileged broker process [E1](https://bugbountylibrary.com/r/blog%3Ablog-electrovolt-io-posts-discord-rce.md)[E3](https://bugbountylibrary.com/r/h1%3A870615.md).

## 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.
- **Google Chrome** (GPU sandbox (gpu.sb)) Chrome < 155, fixed in Chrome 155: CVE-2026-106378: Chrome GPU Sandbox Escape to RCE (CVE-2026-106378). Report: https://bugbountylibrary.com/r/blog%3Apwn-ai-blog-chrome-escape.md
- **Discord** (embed handling / new-window event handler) (version not stated): Discord Desktop - Remote Code Execution. Report: https://bugbountylibrary.com/r/blog%3Ablog-electrovolt-io-posts-discord-rce.md

## Evidence
- E1: https://bugbountylibrary.com/r/blog%3Ablog-electrovolt-io-posts-discord-rce.md
- E2: https://bugbountylibrary.com/r/blog%3Apwn-ai-blog-chrome-escape.md
- E3: https://bugbountylibrary.com/r/h1%3A870615.md
