// Новости

Уязвимость Brotli CVE-2026-111497: патч ОС не лечит Node.js

Уязвимость Brotli CVE-2026-111497: переполнение буфера декодера в Node.js, Python и .NET

Уязвимость Brotli CVE-2026-111497 позволяет намеренно искажённым сжатым потоком переполнить внутренний буфер декодера и в худшем случае выполнить код. Исправления для Node.js, Python и .NET уже вышли, PoC опубликованы. Обновление системной libbrotli при этом не трогает копии декодера, встроенные в приложения и контейнерные образы.

Коротко

  • CVE-2026-111497 — выход за границу 8-байтового буфера в декодере Brotli 1.0.3–1.0.9, 1.1.0 и 1.2.0, вплоть до удалённого выполнения кода (RCE).
  • Исправлено в Brotli 1.0.10/1.1.1/1.2.1, Node.js 22.23.4/24.22.1/26.12.1, Python Brotli 1.2.1 и brotlicffi 1.2.1.0; для .NET вышло экстренное обновление.
  • Системная libbrotli не закрывает Node.js и приложения со своей копией, а блокировка входящих Content-Encoding: br не защищает от вредоносного ответа.
  • PoC опубликованы, о реальных атаках не сообщалось; после патча нужны рестарт процессов и пересборка образов.

Уязвимость Brotli CVE-2026-111497: что сломано и откуда три имени

CVE-2026-111497 — переполнение буфера в потоковом декодере Brotli, библиотеки сжатия без потерь от Google. Уязвимы версии 1.0.3–1.0.9, 1.1.0 и 1.2.0. Node.js перечисляет последствия по нарастающей: падение процесса, раскрытие памяти, удалённое выполнение кода (RCE). Imperva в недавнем отчёте подтверждает, что RCE через эту уязвимость получить можно.

Имён у уязвимости три: HTTP2Shell, Broccoli2Shell и Node2Shell. Первыми её нашли в Node.js, где C-декодер Brotli встроен в рантайм. Затем выяснилось, что ошибка сидит в самой библиотеке и касается всех, кто распаковывает данные Brotli от атакующего: Python-клиентов, Microsoft .NET и любых программ со своей копией декодера.

HTTP/2 здесь ни при чём, несмотря на название. Уязвим разбор сжатых данных, поэтому под угрозой и HTTP/1.1, и любое приложение, которое распаковывает чужой поток Brotli.

Почему декодер пишет за границу буфера?

Декодер путает фатальную ошибку формата с нехваткой данных. По бюллетеню Node.js, некорректное переключение блока (block switch) он принимает за временную потребность в новых байтах, а не за окончательную ошибку.

Вместо того чтобы прервать разбор, потоковый декодер продолжает дописывать входящие байты во внутренний буфер размером восемь байт и в итоге выходит за его границу, затирая соседнюю память. Восемь байт — не предел ущерба: с каждым новым фрагментом потока запись снова уходит за границу, и так, пока атакующий подаёт данные.

Два пути атаки: входящий запрос и чужой ответ

Первый путь — входящий: злоумышленник отправляет серверу запрос со сжатым телом, и тот его распаковывает. Второй — исходящий: приложение само запрашивает URL, а сервер атакующего возвращает вредоносный сжатый ответ.

Второму пути подвержены вебхуки, парсеры, генераторы превью ссылок и интеграции с внешними API. В Python это urllib3[brotli], requests, httpx и aiohttp[speedups], если в окружении стоит уязвимый декодер Brotli. Сам по себе requests не уязвим: смотрите, какой пакет-декодер установлен, в том числе как транзитивная зависимость. Такие клиенты стоит проверять в ходе пентеста API.

Блокировка входящих запросов с Content-Encoding: br на WAF или балансировщике закрывает только первый путь. Вредоносный ответ внешнего сервера она не остановит.

.NET стоит особняком. В воскресенье Microsoft выпустила экстренное обновление и предупредила, что успешная эксплуатация даёт повышение привилегий на системах с уязвимой версией .NET. Перечень версий и номер бюллетеня BleepingComputer не приводит — сверяйтесь с бюллетенем Microsoft.

Какие версии исправлены и почему патч ОС не помогает?

По данным BleepingComputer, исправления попали в исходный код Brotli ещё в феврале, а стабильные релизы Node.js и Google вышли 21 октября. Публичное раскрытие состоялось на следующий день, исправленные пакеты на PyPI появились 23 октября, обновление .NET — в воскресенье.

КомпонентИсправленные версии
Google Brotli1.0.10, 1.1.1, 1.2.1
Node.js22.23.4, 24.22.1, 26.12.1
Brotli для Python1.2.1
brotlicffi1.2.1.0
Microsoft .NETэкстренное обновление, версии не названы

Главная ловушка — встроенная копия декодера. Портал, который отслеживает уязвимость, прямо предупреждает: обновление системной библиотеки Brotli не закрывает риск для Node.js и приложений с собственной копией. Node.js собирает Brotli в свой бинарник, и обновление libbrotli через apt или dnf его не исправит.

Обычное сканирование уязвимостей по пакетам ОС такую копию не видит. Python-пакеты внутри образа покажет SBOM-инструмент вроде syft или trivy image, а версию Brotli в Node.js надёжнее спросить у самого бинарника. По номеру системного пакета без бюллетеня дистрибутива судить тоже нельзя: патч могут бэкпортировать без смены версии.

Что сделать сегодня: версии, процессы и образы

  1. Node.js. Выполните node -v и node -p process.versions.brotli тем же бинарником, который запускает сервис, в том числе внутри контейнера. Нужны 22.23.4, 24.22.1 или 26.12.1.
  2. Python. Запустите pip show Brotli brotlicffi в каждом виртуальном окружении, а не только в системном Python.
  3. .NET. Выполните dotnet –list-runtimes и сверьте результат с бюллетенем Microsoft.
  4. Код. Найдите createBrotliDecompress, BrotliStream, brotli.Decompressor, brotlicffi и обработку Content-Encoding: br. Отметьте, где распаковываются входящие тела, а где — ответы внешних серверов.
  5. Перезапуск. После обновления перезапустите процессы: до рестарта в памяти работает старый код.
  6. Образы. Пересоберите образы контейнеров и выкатите их заново, запущенные контейнеры не латайте на месте. Если пересборка не встроена в конвейер, это повод заняться внедрением DevSecOps.
  7. Если обновиться нельзя. Уберите поддержку Brotli из Python-приложений и заблокируйте на прокси или межсетевом экране входящие запросы с Content-Encoding: br. Ответы внешних серверов эта мера не отсекает.

Заголовок Content-Encoding: br в логах — штатный, а не индикатор атаки. Подозрительны неожиданные падения процессов, которые распаковывают внешние данные. Прежде чем пересобирать образ на таком хосте, сохраните core dump, журналы оркестратора и сам образ. Публичный PoC проверяйте только в изолированной копии, не на продакшене.

Что пока неизвестно

В пересказе BleepingComputer нет оценки CVSS, статуса в каталоге CISA KEV, перечня уязвимых версий .NET и номера бюллетеня Microsoft, не назван и год февральского коммита. О реальных атаках не сообщалось. Но PoC опубликованы, а сценарий с вредоносным ответом требует от атакующего лишь сервера, на который ваше приложение само зайдёт по ссылке.

Частые вопросы

Касается ли HTTP2Shell только HTTP/2?

Нет. Ошибка в декодере Brotli, а не в протоколе: уязвимо любое приложение, которое распаковывает чужие данные Brotli, в том числе по HTTP/1.1.

Закрывает ли обновление системной Brotli сразу и Node.js?

Нет. Node.js несёт свою копию декодера: обновите сам Node.js до 22.23.4, 24.22.1 или 26.12.1 и перезапустите процессы.

Уязвимы ли Python requests и httpx?

Сами клиенты — нет, уязвим декодер под ними. Обновите Brotli до 1.2.1 и brotlicffi до 1.2.1.0 в каждом окружении.

Эксплуатируют ли Node2Shell в реальных атаках?

Публичные PoC есть, но о реальных атаках не сообщалось. Приоритет обновления от этого не снижается.

Если непонятно, где в ваших сервисах распаковываются чужие данные, SecurityLab.pro найдёт эти места и проверит оба пути атаки в ходе пентеста веб-приложений.


← назад в блог