
Proof-of-concept и GLSL-фаззер для CVE-2026-9999 в бэкенде WebGL ANGLE/Metal в Chrome, с идентификацией сборки, подобранными шейдерами и сбором артефактов краша.
| Поле | Значение |
|---|
| CVE | CVE-2026-9999 |
| Вендор / продукт | Google Chrome |
| Затронуто | Chrome < 148.0.7778.216, только macOS [1] |
| Исправлено в | 148.0.7778.216 [1] |
| Воздействие | Выполнение произвольного кода внутри песочницы через специально сформированную HTML-страницу [1] |
| Критичность по Chromium | High [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] |
| Оценка CVSS от NVD (NIST) | Пока не предоставлена [1] |
| CWE | CWE-269 — Некорректное управление привилегиями (обогащение от CISA-ADP) [1] |
| CISA SSVC (2026-05-29) | exploitation: none, automatable: no, technicalImpact: total [1] |
| Опубликовано / последнее изменение | 2026-05-28 / 2026-07-21 [1] |
| Первопричина | Не публична — в Chromium issue 513364480 указано «Permissions Required» [1] |
Следствие для цепочки атаки: выполнение кода «внутри песочницы» [1] означает, что атакующий получает контроль над процессом внутри песочницы (вероятнее всего, GPU-процессом). Для полного захвата браузера дополнительно потребуется отдельный побег из песочницы, который не является частью данной CVE.
Ниже приведены выводы из публичных данных, а не подтверждённые факты:
Поэтому харнес отрабатывает именно эти паттерны, а затем массово мутирует GLSL в поисках падения на стороне рендерера (потеря WebGL-контекста = падение GPU-процесса или его остановка watchdog'ом).
| Файл | Назначение |
|---|---|
cve-2026-9999-poc.html | Самодостаточный PoC-харнес (без зависимостей): определение сборки, 8 подобранных шейдеров для нагрузки на транслятор, GLSL-фаззер с сохранением артефактов падения |
README.md | Этот файл |
Архив Chrome for Testing от Google предоставляет сборки с фиксированной версией, которые не обновляются автоматически. Найдите новейшую уязвимую сборку (затронуто всё, что ниже 148.0.7778.216 [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
Скачайте для вашей архитектуры (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
Распакуйте в лабораторную папку (например, ~/lab/, не в /Applications) и запускайте оттуда.
Если нужной сборки нет в Chrome for Testing, используйте архив снапшотов Chromium (commondatastorage.googleapis.com/chromium-browser-snapshots/Mac/ для Intel, .../Mac_Arm/ для Apple Silicon), индексируемый по позиции коммита — сопоставьте уязвимую версию с позицией ветки через chromium-history, затем возьмите ближайший снапшот. Снапшоты также не обновляются автоматически.
Остановите агенты обновления Keystone и заблокируйте googleupdate.googleapis.com, иначе тестовая сборка незаметно обновит себя за ночь. Для сборок Chrome for Testing не требуется.
Без Metal Chrome рендерит WebGL программно (SwiftShader), и Metal-бэкенд ANGLE не задействуется. В консоли страницы PoC выполните:
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
Это также можно подтвердить на chrome://gpu. Гостевые системы Parallels/VMware Fusion с виртуализацией GPU обычно работают; минимальные конфигурации QEMU/UTM часто откатываются на SwiftShader.
cd <repo dir>
python3 -m http.server 8000
# then browse to http://localhost:8000/cve-2026-9999-poc.html
1) Run curated triggers. Восемь шейдеров нагружают паттерны транслятора, описанные в §2 (выход за границы массива при индексации константой, переполнение целых чисел при расчёте размера массивов, динамическая индексация матриц, нагрузка на развёртку циклов, массивы массивов, discard/swizzle, граничные случаи препроцессора, слишком большие UBO). Следите за результатами [!!] и событиями потери контекста.2) Fuzz. Мутированные GLSL-шейдеры компилируются, линкуются, отрисовываются и считываются в цикле. Следите в логе за CONTEXT LOST.localStorage. Получите его:
localStorage.getItem("cve20269999_poc_fs"); // crashing fragment shader
localStorage.getItem("cve20269999_crashes"); // crash event log
Живой снапшот подозрительного запуска также виден на
chrome://gpuи в консоли macOS (отчёты о падении GPU-процесса).
WEBGL_context_lost ≠ уязвимость. GPU watchdog Chrome убивает долго выполняющиеся шейдеры (триггер loop-unroll-dos и итерации фаззинга с огромным числом итераций циклов намеренно медленные). Отсеките шум: уменьшите SH_ITER или убедитесь, что любой кандидат на падение воспроизводится быстро (< 1 с на итерацию).EXC_BAD_ACCESS), а не завершение watchdog'ом.Соберите уязвимую ревизию Chromium с 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
Затем запустите минимизированный падающий шейдер с включённой валидацией Metal API:
MTL_DEBUG_LAYER=1 out/asan/Chromium.app/Contents/MacOS/Chromium poc.html
Трейс ASAN укажет точную функцию ANGLE/Metal и подтвердит, соответствует ли падение компоненту CVE [1].
(В дальнейшем: когда коммит с исправлением для 148.0.7778.216 станет доступен, выполните diff по third_party/angle/src/libANGLE/renderer/metal/, чтобы установить истинную первопричину, и замените подход с фаззингом на детерминированный триггер.)
exploitation: none [1].Тестируйте только на машинах, которыми вы владеете или на которых вам явно разрешено проводить тестирование. Харнес намеренно компилирует враждебные шейдеры, чтобы обрушить графический процесс, — ожидайте завершений GPU-процесса. Не допускайте уязвимую сборку браузера к производственным сетям.
[1] NVD — CVE-2026-9999: https://nvd.nist.gov/vuln/detail/CVE-2026-9999 * Рекомендация вендора (блог Chrome Releases, обновление Stable Channel): https://chromereleases.googleblog.com/2026/05/stable-channel-update-for-desktop_0877304591.html * Chromium issue 513364480 (доступ ограничен): https://issues.chromium.org/issues/513364480