## https://sploitus.com/exploit?id=8E9682F7-497B-5268-8487-0C28361EC740
# CVE-2026-9999 β Chrome ANGLE/Metal WebGL PoC Hunting Harness (macOS)
---
## 1. Vulnerability summary
| Field | Value |
|---|---|
| CVE | CVE-2026-9999 |
| Vendor / product | Google Chrome |
| Affected | Chrome **/mac-arm64/chrome-mac-arm64.zip
# Intel
https://storage.googleapis.com/chrome-for-testing-public//mac-x64/chrome-mac-x64.zip
```
Unzip into a lab folder (e.g. `~/lab/`, **not** `/Applications`) and launch from there.
### 5.2 Method B β Chromium snapshots
If a specific build is missing from Chrome for Testing, use the Chromium snapshot
archive (`commondatastorage.googleapis.com/chromium-browser-snapshots/Mac/` for Intel,
`.../Mac_Arm/` for Apple Silicon), indexed by commit position β map the vulnerable
version to a branch position via chromium-history, then pull the nearest snapshot.
Snapshots also do not auto-update.
### 5.3 Block auto-updates (only if using a branded build from another source)
Kill the Keystone updater agents and block `googleupdate.googleapis.com`, or the test
build will silently patch itself overnight. Not needed for Chrome for Testing builds.
### 5.4 Verify you are on the Metal backend (critical)
Without Metal, Chrome renders WebGL in software (SwiftShader) and the ANGLE Metal
backend is never touched. In the PoC page's console, run:
```js
const c = document.createElement('canvas'), g = c.getContext('webgl2');
const x = g.getExtension('WEBGL_debug_renderer_info');
console.log(g.getParameter(x.UNMASKED_RENDERER_WEBGL));
// Good: contains "ANGLE Metal Renderer"
// Bad: contains "SwiftShader" -> the vulnerable path is NOT being exercised
```
You can also confirm at `chrome://gpu`. Parallels/VMware Fusion guests with GPU
virtualization usually work; minimal QEMU/UTM setups often fall back to SwiftShader.
---
## 6. Steps to reproduce
1. **Isolate the target.** VM snapshot or dedicated macOS account. Never sign in or
enable sync in the vulnerable build; treat it as compromised by design. (The CVE's
impact is code execution inside a sandbox arriving simply by visiting a web page [1].)
2. **Install the vulnerable build** per Β§5 and verify Β§5.4 passes.
3. **Serve the PoC** (either open the file directly or):
```bash
cd
python3 -m http.server 8000
# then browse to http://localhost:8000/cve-2026-9999-poc.html
```
4. **Check the fingerprint line** printed on load. It should report the build as below
148.0.7778.216 and therefore potentially vulnerable [1]. On patched builds the harness
warns so you don't waste cycles.
5. **Click `1) Run curated triggers`.** Eight shaders stress the translator patterns
described in Β§2 (OOB constant indexing, integer-overflow array sizing, dynamic matrix
indexing, loop-unroll stress, arrays-of-arrays, discard/swizzle, preprocessor edges,
oversized UBOs). Watch for `[!!]` results and context-loss events.
6. **Click `2) Fuzz`.** Mutated GLSL shaders are compiled, linked, drawn to, and
read back in a loop. Watch the log for `CONTEXT LOST`.
7. **On a crash**, the offending shader is persisted to `localStorage`. Retrieve it:
```js
localStorage.getItem("cve20269999_poc_fs"); // crashing fragment shader
localStorage.getItem("cve20269999_crashes"); // crash event log
```
8. **Minimize and re-test** the crashing shader in isolation (5+ consecutive runs) to
confirm determinism.
9. **Confirm root cause** with an ASAN build before attributing anything to
CVE-2026-9999 β see Β§8.
> Live snapshot of a suspicious run is also visible at `chrome://gpu` and in macOS
> Console (GPU process crash reports).
---
## 7. Interpreting results / known false positives
* **`WEBGL_context_lost` β vulnerability.** Chrome's GPU watchdog kills long-running
shaders (the `loop-unroll-dos` trigger and fuzz iterations with huge loop counts are
designed to be slow). Silence the noise: reduce `SH_ITER`, or confirm any candidate
crash reproduces quickly (< 1 s per iteration).
* A **real memory-safety crash** should reproduce deterministically from the minimized
shader and show a distinct crash signature in Console (e.g., `EXC_BAD_ACCESS`) rather
than a watchdog termination.
* Only an ASAN report pinpointing the ANGLE Metal backend is solid evidence you have
found *this* bug as opposed to an unrelated driver hiccup.
---
## 8. Root-cause confirmation: ASAN build (optional but strongly recommended)
Build a vulnerable revision of Chromium with AddressSanitizer:
```bash
fetch chromium
cd src
git checkout tags/148.0.7778.215 # last tag before the fix
gn gen out/asan --args='is_asan=true is_debug=false symbol_level=1 dcheck_always_on=true'
autoninja -C out/asan chrome
```
Then run the minimized crashing shader with Metal API validation enabled:
```bash
MTL_DEBUG_LAYER=1 out/asan/Chromium.app/Contents/MacOS/Chromium poc.html
```
The ASAN trace will name the exact ANGLE/Metal function and confirm whether the crash
matches the CVE's component [1].
(Downstream: once the fix commit for 148.0.7778.216 is visible, diff
`third_party/angle/src/libANGLE/renderer/metal/` to pinpoint the true root cause and
replace the fuzzing approach with a deterministic trigger.)
---
## 9. Limitations
* **No public root cause or PoC exists.** The Chromium issue is restricted ("Permissions
Required") [1]; this harness is hypothesis-driven.
* **No known in-the-wild exploitation.** CISA's SSVC enrichment (2026-05-29) records
`exploitation: none` [1].
* **Sandbox-contained impact only** [1] β this PoC, even if it produces code execution,
addresses only the sandboxed-process stage of a real attack chain.
* macOS-only target [1]; do not draw conclusions from runs on other platforms.
---
## 10. Safety & legal
Test only on machines you own or are explicitly authorized to test. The harness
intentionally compiles adversarial shaders to crash a graphics process β expect GPU
process kills. Keep the vulnerable browser build off production networks.
---
## 11. References
[1] NVD β CVE-2026-9999: https://nvd.nist.gov/vuln/detail/CVE-2026-9999
* Vendor advisory (Chrome Releases blog, Stable Channel update):
https://chromereleases.googleblog.com/2026/05/stable-channel-update-for-desktop_0877304591.html
* Chromium issue 513364480 (access-restricted):
https://issues.chromium.org/issues/513364480