
Proof-of-concept e fuzzer GLSL per CVE-2026-9999 nel backend WebGL ANGLE/Metal di Chrome, con fingerprinting delle build, shader selezionati e acquisizione degli artefatti di crash.
| Campo | Valore |
|---|
| CVE | CVE-2026-9999 |
| Vendor / prodotto | Google Chrome |
| Interessate | Chrome < 148.0.7778.216, solo macOS [1] |
| Corretta in | 148.0.7778.216 [1] |
| Impatto | Esecuzione di codice arbitrario all'interno di una sandbox tramite una pagina HTML appositamente predisposta [1] |
| Gravità Chromium | Alta [1] |
| CVSS 3.1 (CISA-ADP) | 8.8 ALTA — CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H [1] |
| Valutazione CVSS NVD (NIST) | Non ancora fornita [1] |
| CWE | CWE-269 — Gestione impropria dei privilegi (arricchimento da parte di CISA-ADP) [1] |
| CISA SSVC (2026-05-29) | exploitation: none, automatable: no, technicalImpact: total [1] |
| Pubblicata / ultima modifica | 2026-05-28 / 2026-07-21 [1] |
| Causa principale | Non pubblica — l'issue Chromium 513364480 mostra "Permissions Required" [1] |
Implicazione per la catena di attacco: l'esecuzione di codice "all'interno di una sandbox" [1] significa che un attaccante ottiene il controllo di un processo in sandbox (molto probabilmente il processo GPU). Un takeover completo del browser richiederebbe inoltre una separata fuga dalla sandbox che non fa parte di questa CVE.
Quanto segue è un'inferenza basata su documenti pubblici, non fatti confermati:
L'harness quindi esercita esattamente questi pattern e poi muta GLSL su larga scala per cercare un crash lato renderer (WebGL context lost = crash del processo GPU o kill da parte del watchdog).
| File | Scopo |
|---|---|
cve-2026-9999-poc.html | Harness PoC autonomo (nessuna dipendenza): fingerprinting della build, 8 shader curati per stressare il traduttore, fuzzer GLSL con acquisizione degli artefatti di crash |
README.md | Questo file |
L'archivio Chrome for Testing di Google fornisce build ancorate a una versione specifica che non si aggiornano automaticamente. Trova la build vulnerabile più recente (tutto ciò che è inferiore a 148.0.7778.216 è affetto [1]):
import json, urllib.request
data = json.load(urllib.request.urlopen(
"https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json"))
key = lambda v: tuple(int(x) for x in v.split('.'))
fix = (148, 0, 7778, 216)
cands = sorted((v["version"] for v in data["versions"]
if "chrome" in v.get("downloads", {}) and key(v["version"]) < fix), key=key)
print(cands[-5:]) # pick the last (newest vulnerable) entry
Scarica per la tua architettura (uname -m):
# Apple Silicon
https://storage.googleapis.com/chrome-for-testing-public/<VERSION>/mac-arm64/chrome-mac-arm64.zip
# Intel
https://storage.googleapis.com/chrome-for-testing-public/<VERSION>/mac-x64/chrome-mac-x64.zip
Decomprimi in una cartella di laboratorio (es. ~/lab/, non /Applications) e avvia da lì.
Se una build specifica non è disponibile in Chrome for Testing, usa l'archivio degli snapshot Chromium (commondatastorage.googleapis.com/chromium-browser-snapshots/Mac/ per Intel, .../Mac_Arm/ per Apple Silicon), indicizzato per posizione di commit — mappa la versione vulnerabile a una posizione di branch tramite chromium-history, quindi scarica lo snapshot più vicino. Anche gli snapshot non si aggiornano automaticamente.
Termina gli agenti di aggiornamento Keystone e blocca googleupdate.googleapis.com, altrimenti la build di test si auto-patcha silenziosamente durante la notte. Non necessario per le build di Chrome for Testing.
Senza Metal, Chrome esegue il rendering WebGL via software (SwiftShader) e il backend Metal di ANGLE non viene mai toccato. Nella console della pagina PoC, esegui:
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
Puoi anche verificarlo su chrome://gpu. Le macchine virtuali Parallels/VMware Fusion con virtualizzazione GPU di solito funzionano; le configurazioni minimali QEMU/UTM spesso ripiegano su SwiftShader.
cd <repo dir>
python3 -m http.server 8000
# then browse to http://localhost:8000/cve-2026-9999-poc.html
1) Run curated triggers. Otto shader stressano i pattern del traduttore descritti in §2 (indicizzazione costante fuori dai limiti, dimensionamento array con overflow di interi, indicizzazione dinamica di matrici, stress da loop unrolling, array di array, discard/swizzle, casi limite del preprocessore, UBO sovradimensionati). Controlla i risultati [!!] e gli eventi di context loss.2) Fuzz. Gli shader GLSL mutati vengono compilati, linkati, usati per il rendering e riletti in loop. Controlla il log per CONTEXT LOST.localStorage. Recuperalo:
localStorage.getItem("cve20269999_poc_fs"); // crashing fragment shader
localStorage.getItem("cve20269999_crashes"); // crash event log
Uno snapshot live di un'esecuzione sospetta è visibile anche su
chrome://gpue nella Console di macOS (report di crash del processo GPU).
WEBGL_context_lost ≠ vulnerabilità. Il watchdog GPU di Chrome termina gli shader a lunga esecuzione (il trigger loop-unroll-dos e le iterazioni di fuzz con conteggi di loop enormi sono progettati per essere lenti). Elimina il rumore: riduci SH_ITER, oppure conferma che qualsiasi crash candidato si riproduca rapidamente (< 1 s per iterazione).EXC_BAD_ACCESS) piuttosto che una terminazione del watchdog.Compila una revisione vulnerabile di Chromium con AddressSanitizer:
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
Quindi esegui lo shader minimizzato che causa il crash con la validazione dell'API Metal abilitata:
MTL_DEBUG_LAYER=1 out/asan/Chromium.app/Contents/MacOS/Chromium poc.html
La traccia ASAN indicherà l'esatta funzione ANGLE/Metal e confermerà se il crash corrisponde al componente della CVE [1].
(A valle: quando il commit del fix per 148.0.7778.216 sarà visibile, esegui il diff di third_party/angle/src/libANGLE/renderer/metal/ per individuare la vera causa principale e sostituire l'approccio di fuzzing con un trigger deterministico.)
exploitation: none [1].Esegui i test solo su macchine di tua proprietà o per le quali hai l'esplicita autorizzazione. L'harness compila intenzionalmente shader avversari per mandare in crash un processo grafico — aspettati terminazioni del processo GPU. Tieni la build vulnerabile del browser lontana dalle reti di produzione.
[1] NVD — CVE-2026-9999: https://nvd.nist.gov/vuln/detail/CVE-2026-9999 * Avviso del vendor (blog Chrome Releases, aggiornamento del canale Stable): https://chromereleases.googleblog.com/2026/05/stable-channel-update-for-desktop_0877304591.html * Issue Chromium 513364480 (accesso limitato): https://issues.chromium.org/issues/513364480