
Preuve de concept et fuzzer GLSL pour CVE-2026-9999 dans le backend WebGL ANGLE/Metal de Chrome, avec fingerprinting de build, shaders sélectionnés et capture d'artefacts de crash.
| Champ | Valeur |
|---|---|
| CVE | CVE-2026-9999 |
| Éditeur / produit | Google Chrome |
| Versions concernées | Chrome < 148.0.7778.216, macOS uniquement [1] |
| Corrigé dans | 148.0.7778.216 [1] |
| Impact | Exécution de code arbitraire dans un sandbox via une page HTML spécialement conçue [1] |
| Sévérité Chromium | Élevée [1] |
| CVSS 3.1 (CISA-ADP) | 8.8 ÉLEVÉE — CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H [1] |
| Évaluation CVSS NVD (NIST) | Pas encore fournie [1] |
| CWE | CWE-269 — Gestion inappropriée des privilèges (enrichissement par CISA-ADP) [1] |
| CISA SSVC (2026-05-29) | exploitation: none, automatable: no, technicalImpact: total [1] |
| Publié / Dernière modification | 2026-05-28 / 2026-07-21 [1] |
| Cause racine | Non publique — le ticket Chromium 513364480 affiche « Permissions Required » [1] |
Implication pour la chaîne d'attaque : l'exécution de code « dans un sandbox » [1] signifie qu'un attaquant prend le contrôle d'un processus sandboxé (le plus vraisemblablement le processus GPU). Une prise de contrôle complète du navigateur nécessiterait en outre une évasion de sandbox distincte qui ne fait pas partie de cette CVE.
Ce qui suit est une déduction fondée sur les informations publiques, et non des faits confirmés :
Le harnais exerce donc exactement ces motifs, puis mute le GLSL à grande échelle pour traquer un crash côté moteur de rendu (contexte WebGL perdu = crash du processus GPU ou mise à mort par le watchdog).
| Fichier | Rôle |
|---|---|
cve-2026-9999-poc.html | Harnais de PoC autonome (aucune dépendance) : empreinte de build, 8 shaders de stress du traducteur soigneusement sélectionnés, fuzzer GLSL avec capture des artefacts de crash |
README.md | Ce fichier |
L'archive Chrome for Testing de Google fournit des builds épinglés à une version qui ne se mettent pas à jour automatiquement. Trouvez le build vulnérable le plus récent (toutes les versions inférieures à 148.0.7778.216 sont concernées [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
Téléchargez pour votre architecture (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
Décompressez dans un dossier de laboratoire (par ex. ~/lab/, pas /Applications) puis lancez à partir de là.
Si un build précis manque dans Chrome for Testing, utilisez l'archive d'instantanés Chromium (commondatastorage.googleapis.com/chromium-browser-snapshots/Mac/ pour Intel, .../Mac_Arm/ pour Apple Silicon), indexée par position de commit — faites correspondre la version vulnérable à une position de branche via chromium-history, puis récupérez l'instantané le plus proche. Les instantanés ne se mettent pas non plus à jour automatiquement.
Tuez les agents de mise à jour Keystone et bloquez googleupdate.googleapis.com, sinon le build de test se corrigera silencieusement tout seul pendant la nuit. Inutile pour les builds Chrome for Testing.
Sans Metal, Chrome rend le WebGL par logiciel (SwiftShader) et le backend ANGLE Metal n'est jamais sollicité. Dans la console de la page PoC, exécutez :
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
Vous pouvez aussi le confirmer sur chrome://gpu. Les invités Parallels/VMware Fusion avec virtualisation GPU fonctionnent généralement ; les configurations minimales QEMU/UTM retombent souvent sur SwiftShader.