Уязвимость CVE-2026-111497 в декодере сжатия Brotli от Google позволяет выполнить запись за пределами буфера при обработке специально сформированных сжатых данных. Поскольку множество программных продуктов — от Node.js и Bun до Python-пакетов и прокси-серверов Envoy — включают собственную копию этого декодера, масштаб затронутого ПО оказался значительным. Исследователи из Imperva продемонстрировали выполнение произвольного кода на немодифицированной сборке Node.js 24.22.0 для Linux arm64. Патчи уже доступны: обновление рантайма или библиотеки — единственный надёжный способ устранения.
Техническая суть уязвимости
Уязвимость классифицируется как CWE-787 (запись за пределами буфера) и находится в C-коде декодера Brotli. Согласно записи в GitHub Advisory Database, проблема возникает при обработке потока Brotli, в котором объявленная структура блоков приводит к невозможному переходу типа блока. Уязвимый декодер интерпретирует такое состояние как запрос дополнительных данных и продолжает работу в невалидном состоянии, что приводит к записи за пределами выделенного буфера. Исправленная версия вместо этого останавливает декодирование с ошибкой формата.
Оценки критичности различаются в зависимости от контекста продукта. GitHub Advisory Database указывает 9.2 Critical по CVSS v4.0. Red Hat оценивает уязвимость как Important с баллом 8.1 по CVSS v3.1. Node.js присваивает рейтинг High. Istio в контексте своего продукта указывает 7.7. Такой разброс отражает разные условия достижимости уязвимого кода в каждом продукте, и ни одну из этих оценок не следует воспринимать как универсальную.
Примечательна история исправления: патч, закрывающий корневую причину, был добавлен в исходный код Brotli ещё 27 февраля, однако на тот момент не было известно, что изменение устраняет уязвимость безопасности, и нового релиза Brotli с этим исправлением не выходило до 21 октября. Подробности доступны на странице NVD.
Затронутые продукты и условия эксплуатации
Ключевая особенность этой уязвимости — каждый затронутый продукт поставляет собственную копию декодера Brotli, поэтому каждый должен обновляться независимо. Подтверждённый список затронутого ПО:
- Node.js — линейки 22.x, 24.x и 26.x. Исправленные версии: 22.23.4, 24.22.1 и 26.12.1 (бюллетень Node.js)
- Bun — версии от 1.0.21 до 1.4.3. Исправлено в 1.4.4 (бюллетень Bun)
- Python-пакет Brotli (PyPI) — версии от 1.0.3 до 1.2.0. Исправлено в 1.2.1
- Python-пакет brotlicffi (PyPI) — аналогично затронут
- Envoy — при включённой декомпрессии Brotli (бюллетень Envoy)
- Istio — версии 1.29.0–1.29.8, 1.30.0–1.30.5, 1.31.0–1.31.1 при использовании затронутого пути Envoy
Условия эксплуатации зависят от конфигурации. Программа уязвима только если декодирует данные Brotli из недоверенного источника. Для Node.js и Bun это происходит при чтении ответа с заголовком Content-Encoding: br через встроенный fetch(), а также при декомпрессии тела запроса через middleware. Сам по себе HTTP-сервер Node.js не декодирует тело запроса в формате Brotli — для этого нужен явный вызов или middleware. Согласно документации Express 5, middleware express.json(), express.urlencoded(), express.text() и express.raw() теперь поддерживают декомпрессию Brotli, что создаёт входящий вектор атаки на маршрутах, где эти обработчики активны.
В Python ситуация особенно коварна: достаточно наличия установленного пакета Brotli или brotlicffi, чтобы HTTP-клиенты requests, urllib3, httpx и aiohttp начали автоматически декодировать ответы в формате Brotli — без явного импорта Brotli в коде приложения.
Для Envoy и Istio уязвимость достижима только при включённой декомпрессии Brotli через соответствующий фильтр.
Статус эксплуатации и демонстрация
Статус эксплуатации — доступен публичный PoC. Исследователи из Imperva в рамках демонстрации Node2Shell добились выполнения произвольного кода на стандартной сборке Node.js 24.22.0 для Linux arm64, без отладчика и без модифицированной сборки. Эксплойт воспроизводился через оба вектора — тело входящего запроса (Express 5) и ответ, полученный через fetch(). При этом эксплуатация не была стабильной и требовала нескольких попыток; другие архитектуры и линейки 22.x и 26.x не тестировались.
По данным бюллетеня Vercel, исследователи также продемонстрировали утечку памяти процесса и выполнение команд на непропатченных линейках Node.js. Эксплуатации в реальных атаках на момент публикации не зафиксировано. Уязвимость не внесена в каталог CISA KEV.
Ограничения WAF-защиты
Vercel развернул правила WAF 21 октября для блокировки входящих атак. Однако, как прямо указано в бюллетене Vercel, эти правила не покрывают ответы в формате Brotli, которые приложение получает от внешних серверов. Это принципиальное ограничение: WAF-телеметрия способна выявить часть попыток атаки на входящем трафике, но не может защитить от вредоносных ответов, полученных приложением при обращении к внешним ресурсам. Поэтому инвентаризация рантаймов и пересборка контейнерных образов остаются обязательными.
Рекомендации
Приоритет обновления следует отдать интернет-доступным сервисам и клиентам, которые автоматически декодируют недоверенные данные Brotli. Сам факт приёма HTTP-трафика не означает уязвимость Node.js — необходимо наличие кода или middleware, выполняющего декомпрессию.
- Обновите рантайм или библиотеку до исправленной версии. После обновления перезапустите сервис и пересоберите контейнерные образы — работающий процесс использует старый декодер до перезапуска.
- Линейки Node.js 20.x и старше не получат исправления — необходима миграция на поддерживаемую линейку.
- Если немедленное обновление невозможно: отклоняйте входящие запросы с заголовком
Content-Encoding: brдо того, как прокси или парсер начнёт декомпрессию; отключите автоматическую декомпрессию Brotli в HTTP-клиентах. - В Python: удалите пакеты Brotli и brotlicffi, чтобы клиенты вернулись к gzip и deflate.
- Проверьте сканеры зависимостей: запись CVE ссылается на репозиторий Google Brotli, а не на PyPI-пакеты, и GitHub Advisory на момент публикации не указывал затронутый пакет — Dependabot может не сработать. Записи PYSEC-2026-4322 и PYSEC-2026-4323 добавлены 23 октября; проверяйте установленные версии вручную.
Удаление заголовка br из Accept-Encoding само по себе не защищает: сервер может отправить ответ в формате Brotli независимо от предпочтений клиента. Для Node.js обходного пути внутри рантайма не опубликовано — обновление является единственным способом устранения уязвимости.
Обновите все экземпляры затронутых рантаймов и библиотек, уделив первоочередное внимание сервисам, обрабатывающим недоверенный Brotli-трафик в обоих направлениях — как на входе, так и при получении ответов от внешних серверов. Ранее мы писали об исправлениях безопасности в продуктах Google — CVE-2026-111497 подтверждает, что компоненты Google, встроенные в сторонние продукты, требуют отдельного отслеживания и обновления.












