# Sandbox to native execution bridge

Sandboxed code reaching a native loader, debug channel or re-encoding hook that runs or rewrites code

_Area: Memory corruption and native code. Seen in 2 disclosed reports; 2 confirmed bounties: $2,540 and $3,000; latest 2023-10-10. Updated 2026-11-02._

## How it works
A sandbox blocks the obvious native-execution paths (addon loading, direct syscalls, file access). The assumption that breaks is that the blocked list is complete. If any reachable API still loads native code, or a debug channel is reachable from page code, the boundary is gone: native code runs in-process with the sandbox's own privileges and can switch the restrictions off [E3](https://bugbountylibrary.com/r/h1%3A2091137.md). A second shape: a value is sanitized, then re-encoded through a method user code can overwrite, so the checked value is not the value used [E2](https://bugbountylibrary.com/r/h1%3A2434811.md). A third: a desktop app embeds a browser engine and leaves its debug interface reachable from the pages it renders [E1](https://bugbountylibrary.com/r/h1%3A1274695.md).

## Where it shows up
- Sandbox/permission models that block native addons but leave other native-loading APIs open: `crypto.setEngine()`, FFI, JIT, `dlopen` paths [E3](https://bugbountylibrary.com/r/h1%3A2091137.md)
- Sanitize-then-re-encode flows: a path is validated, then passed through `Buffer.from(...)`, whose internals call a prototype method user code can overwrite [E2](https://bugbountylibrary.com/r/h1%3A2434811.md)
- Embedded browsers launched with `--remote-debugging-port` instead of `--remote-debugging-pipe` [E1](https://bugbountylibrary.com/r/h1%3A1274695.md)
- Debug GUIDs or tokens reachable from rendered page JS, or guessable via port scanning [E1](https://bugbountylibrary.com/r/h1%3A1274695.md)
- Any post-validation conversion that routes through a replaceable prototype method [E2](https://bugbountylibrary.com/r/h1%3A2434811.md)

## How to review
Enumerate every API reachable from sandboxed code that can load or execute native code, and confirm each is blocked, not just the addon loader [E3](https://bugbountylibrary.com/r/h1%3A2091137.md). For sanitization, the invariant is: the value checked is the value used. No user-replaceable method may run between the check and the sink; re-encoding must use a non-overridable primitive [E2](https://bugbountylibrary.com/r/h1%3A2434811.md). For embedded browsers, the debug channel must not be reachable from page JS — pipe, not port [E1](https://bugbountylibrary.com/r/h1%3A1274695.md).

## How finders spotted it
- Noticed the embedded Chrome used a remote-debugging WebSocket port rather than a pipe, making the debug channel reachable from page JS; then used a known Chrome XSS and clickjacking to obtain the debug GUID [E1](https://bugbountylibrary.com/r/h1%3A1274695.md)
- Reasoned that earlier patches fixed `path.resolve` and `Buffer.from` replacement, but `Buffer.from`'s internal call to `Buffer.prototype.utf8Write` stayed monkey-patchable, giving a hook after sanitization [E2](https://bugbountylibrary.com/r/h1%3A2434811.md)
- Observed the permission model blocked native addons by default but overlooked `crypto.setEngine()`, which also loads native code; hypothesized it could bypass and disable the model [E3](https://bugbountylibrary.com/r/h1%3A2091137.md)

## Variants seen
- Debug-channel exposure in an embedded browser leading to file write and persistent RCE [E1](https://bugbountylibrary.com/r/h1%3A1274695.md)
- Post-sanitization re-encoding through an overwritable prototype method [E2](https://bugbountylibrary.com/r/h1%3A2434811.md)
- Native code loaded via a crypto engine API, disabling the permission model in-process [E3](https://bugbountylibrary.com/r/h1%3A2091137.md)

## Impact and severity
Outcomes ranged from reading files outside the allowed directory [E2](https://bugbountylibrary.com/r/h1%3A2434811.md) to full RCE on restart [E1](https://bugbountylibrary.com/r/h1%3A1274695.md) and complete privilege escalation with all later JS unrestricted [E3](https://bugbountylibrary.com/r/h1%3A2091137.md). Impact rose when native code could disable the sandbox itself rather than just escape one check [E3](https://bugbountylibrary.com/r/h1%3A2091137.md), and when the debug channel allowed a persistent file write [E1](https://bugbountylibrary.com/r/h1%3A1274695.md). Bounties were near 2.5k, with the highest at 3k [E1](https://bugbountylibrary.com/r/h1%3A1274695.md)[E2](https://bugbountylibrary.com/r/h1%3A2434811.md)[E3](https://bugbountylibrary.com/r/h1%3A2091137.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.
- **Node.js**: OpenSSL engines can be used to bypass and/or disable the Node.js permission model (CVE-2023-30586). Report: https://bugbountylibrary.com/r/h1%3A2091137.md

## Evidence
- E1: https://bugbountylibrary.com/r/h1%3A1274695.md
- E2: https://bugbountylibrary.com/r/h1%3A2434811.md
- E3: https://bugbountylibrary.com/r/h1%3A2091137.md
