
Prova de conceito e fuzzer GLSL para o CVE-2026-9999 no backend WebGL ANGLE/Metal do Chrome, com fingerprinting de build, shaders selecionados e captura de artefatos de crash.
| Campo | Valor |
|---|
| CVE | CVE-2026-9999 |
| Fornecedor / produto | Google Chrome |
| Afetado | Chrome < 148.0.7778.216, somente macOS [1] |
| Corrigido em | 148.0.7778.216 [1] |
| Impacto | Execução arbitrária de código dentro de um sandbox por meio de uma página HTML especialmente criada [1] |
| Severidade Chromium | Alta [1] |
| CVSS 3.1 (CISA-ADP) | 8.8 HIGH — CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H [1] |
| Avaliação CVSS NVD (NIST) | Ainda não fornecida [1] |
| CWE | CWE-269 — Gerenciamento inadequado de privilégios (enriquecimento pela CISA-ADP) [1] |
| CISA SSVC (2026-05-29) | exploitation: none, automatable: no, technicalImpact: total [1] |
| Publicado / última modificação | 2026-05-28 / 2026-07-21 [1] |
| Causa raiz | Não pública — a issue 513364480 do Chromium mostra "Permissions Required" [1] |
Implicação para a cadeia de ataque: a execução de código "dentro de um sandbox" [1] significa que um atacante obtém o controle de um processo em sandbox (provavelmente o processo de GPU). Uma tomada completa do navegador exigiria adicionalmente uma fuga de sandbox separada que não faz parte deste CVE.
O seguinte é uma inferência a partir do registro público, não fatos confirmados:
Portanto, o harness exercita exatamente esses padrões e então muta GLSL em escala para caçar um crash no lado do renderizador (WebGL context lost = crash do processo de GPU ou kill pelo watchdog).
| Arquivo | Finalidade |
|---|---|
cve-2026-9999-poc.html | Harness PoC autocontido (sem dependências): fingerprinting de build, 8 shaders selecionados de estresse do tradutor, fuzzer GLSL com captura de artefatos de crash |
README.md | Este arquivo |
O arquivo Chrome for Testing do Google fornece builds fixados em versões específicas que não são atualizados automaticamente. Encontre o build vulnerável mais recente (tudo abaixo de 148.0.7778.216 é afetado [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
Baixe para a sua arquitetura (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
Descompacte em uma pasta de laboratório (ex.: ~/lab/, não /Applications) e execute a partir dela.
Se um build específico não estiver disponível no Chrome for Testing, use o arquivo de snapshots do Chromium (commondatastorage.googleapis.com/chromium-browser-snapshots/Mac/ para Intel, .../Mac_Arm/ para Apple Silicon), indexado por posição de commit — mapeie a versão vulnerável para uma posição de branch via chromium-history e baixe o snapshot mais próximo. Snapshots também não são atualizados automaticamente.
Encerre os agentes de atualização do Keystone e bloqueie googleupdate.googleapis.com; caso contrário, o build de teste se atualizará silenciosamente durante a noite. Não é necessário para builds do Chrome for Testing.
Sem Metal, o Chrome renderiza WebGL por software (SwiftShader) e o backend ANGLE Metal nunca é acionado. No console da página do PoC, execute:
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
Você também pode confirmar em chrome://gpu. Convidados de Parallels/VMware Fusion com virtualização de GPU geralmente funcionam; configurações mínimas de QEMU/UTM frequentemente recorrem ao SwiftShader.
cd <repo dir>
python3 -m http.server 8000
# then browse to http://localhost:8000/cve-2026-9999-poc.html
1) Run curated triggers. Oito shaders exercitam os padrões do tradutor descritos na §2 (indexação constante fora dos limites, dimensionamento de arrays com estouro de inteiro, indexação dinâmica de matrizes, estresse de desenrolamento de loop, arrays de arrays, discard/swizzle, casos extremos de pré-processador, UBOs superdimensionados). Fique atento a resultados [!!] e eventos de perda de contexto.2) Fuzz. Shaders GLSL mutados são compilados, vinculados, renderizados e lidos de volta em um loop. Observe o log em busca de CONTEXT LOST.localStorage. Recupere-o:
localStorage.getItem("cve20269999_poc_fs"); // crashing fragment shader
localStorage.getItem("cve20269999_crashes"); // crash event log
Um snapshot ao vivo de uma execução suspeita também é visível em
chrome://gpue no Console do macOS (relatórios de crash do processo de GPU).
WEBGL_context_lost ≠ vulnerabilidade. O watchdog de GPU do Chrome encerra shaders de execução prolongada (o gatilho loop-unroll-dos e as iterações de fuzz com contagens enormes de loop são projetados para serem lentos). Elimine o ruído: reduza SH_ITER ou confirme se qualquer crash candidato se reproduz rapidamente (< 1 s por iteração).EXC_BAD_ACCESS) em vez de uma terminação pelo watchdog.Compile uma revisão vulnerável do Chromium com 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
Em seguida, execute o shader minimizado que causa o crash com a validação da API Metal ativada:
MTL_DEBUG_LAYER=1 out/asan/Chromium.app/Contents/MacOS/Chromium poc.html
O trace ASAN nomeará a função exata do ANGLE/Metal e confirmará se o crash corresponde ao componente do CVE [1].
(Posteriormente: quando o commit da correção para 148.0.7778.216 estiver visível, faça diff em third_party/angle/src/libANGLE/renderer/metal/ para identificar a verdadeira causa raiz e substitua a abordagem de fuzzing por um gatilho determinístico.)
exploitation: none [1].Teste apenas em máquinas suas ou nas quais você tenha autorização explícita para testar. O harness compila intencionalmente shaders adversários para derrubar um processo gráfico — espere encerramentos do processo de GPU. Mantenha o build vulnerável do navegador fora de redes de produção.
[1] NVD — CVE-2026-9999: https://nvd.nist.gov/vuln/detail/CVE-2026-9999 * Aviso do fornecedor (blog Chrome Releases, atualização do canal estável): https://chromereleases.googleblog.com/2026/05/stable-channel-update-for-desktop_0877304591.html * Issue 513364480 do Chromium (acesso restrito): https://issues.chromium.org/issues/513364480