Уязвимость HTTP2Shell в Brotli затрагивает не только Node.js, но и HTTP-клиенты

Уязвимость декодера Brotli затрагивает не только Node.js, но и Python-библиотеки, HTTP-клиенты и другие приложения. После обновления зависимостей нужно пересобрать и развернуть приложения.

· 4 мин чтения · 5 комментариев

Уязвимость декодера Brotli, о которой сначала сообщили в связи с Node.js, затрагивает и другие библиотеки и приложения, работающие с HTTP. Как пишет Aikido 24 октября 2026 года, ошибка CVE-2026-111497 возникает при распаковке специально подготовленных данных. Исправления уже доступны, но обновить зависимость в репозитории недостаточно: уязвимый декодер может остаться внутри собранного приложения или контейнера.

Почему Node2Shell стала HTTP2Shell

Brotli используют для сжатия данных при передаче по HTTP, в том числе HTML, CSS и JavaScript. Проблема находится в декодере: подготовленный поток может привести к записи за пределами выделенной памяти. Затронуты версии Google Brotli с 1.0.3 по 1.2.0 на всех платформах. Оценка уязвимости — 9,2 по CVSS 4.0.

Ошибка проявляется при переключении блоков сжатого потока. Прежде один результат функции мог означать как неверный формат, так и нехватку входных данных. Вызывающий код не всегда различал эти ситуации, а быстрый путь обработки не проверял результат. Декодирование могло продолжиться с прежним состоянием блока; исправление останавливает его при ошибке формата.

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

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

Где искать уязвимый декодер

В Python затронуты пакет Brotli версии 1.2.0 и старше и brotlicffi ветки 1.2.0.x. Разработчику необязательно импортировать их напрямую. Если они установлены, urllib3 и работающий через него requests могут автоматически декодировать Brotli-ответы. Поддержку также используют httpx с дополнением для Brotli и aiohttp при наличии пакета. Он может попасть в проект и через другую зависимость, например Scrapy.

Для Python исправленные версии — Brotli 1.2.1 и brotlicffi 1.2.1.0. Для Node.js названы 22.23.4, 24.22.1 и 26.12.1 в соответствующих поддерживаемых ветках; для Bun — 1.4.4. Исправления для Envoy входят в 1.40.0, 1.39.3, 1.38.6 и 1.37.8, для Istio — в 1.29.9, 1.30.6 и 1.31.2. При этом ветки Envoy 1.36 и Istio 1.29 больше не поддерживаются, хотя исправления для них тоже указаны в материале. Системный пакет может получить патч от поставщика без смены номера на версию, совпадающую с выпуском Brotli.

Есть пробел и в привычной проверке зависимостей. По состоянию на 23 октября базы рекомендаций ещё не связывали этот CVE с пакетами Brotli и brotlicffi на PyPI. Поэтому pip-audit, Dependabot и Safety пока могут не показать уязвимую версию. Отсутствие предупреждения не означает, что декодера нет.

Что делать сайтам и приложениям

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

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

Пока обновление невозможно, входящие запросы с Content-Encoding: br можно отклонять до распаковки. Для исходящих запросов одного удаления br из Accept-Encoding мало: сервер может прислать Brotli-ответ и без этого заголовка. Нужно также отключить декодирование таких ответов либо отклонять их до начала обработки тела. В Python, где Brotli необязателен, временно можно удалить оба пакета и зависимости, которые установят их снова. Но некоторые ответы после этого станут нечитаемыми, а декодеры внутри других компонентов никуда не исчезнут.

Моё мнение

Я бы не начинал с поиска слова Brotli в собственном коде. Пятилетний «временный» сервис вполне может распаковывать ответы через зависимость, о которой его автор давно забыл. Сначала посмотрел бы на установленные пакеты и запущенные образы, затем — на места, куда приходят данные с чужих серверов. Галочка в отчёте сканера, который пока не связывает CVE с пакетами PyPI, в этот раз успокаивает слишком рано.

Источники

Откуда новость. Текст — пересказ своими словами, факты — из источника, мнение — автора.

  1. Node2Shell evolves to HTTP2Shell, blast radius affects many HTTP libs and apps www.aikido.dev

Об авторе

Лев Іваненко

опытный full-stack-разработчик

Делаю внутренние кабинеты и магазины, чаще всего разбираю старый код, который «временно» живёт уже пять лет. В свободное время проверяю, сколько библиотек можно удалить без последствий.

Все публикации автора

Бэкенд 4 мин чтения

В декодере Brotli нашли уязвимость с риском удалённого выполнения кода

В C-декодере Brotli обнаружили уязвимость, которая может привести к удалённому выполнению кода. Разработчикам стоит проверить версии Node.js, Python-библиотек и встроенные копии декодера.

Бэкенд 4 мин чтения

В ядре PHP исправили уязвимости, позволяющие удалённо выполнить код

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

Бэкенд 4 мин чтения

Уязвимость PHP есть, но опубликованные примеры эксплуатации вызывают вопросы

Автор публикации считает, что распространённые PoC не доказывают возможность атаковать стандартный сервер PHP. При этом уязвимость реальна, и затронутые серверы нужно исправить.

Написать комментарий

Не публикуется. Пришлём ссылку, чтобы подтвердить комментарий.

Без ссылок и рекламы. Первый комментарий публикуется после проверки. Отправляя комментарий, вы соглашаетесь с политикой конфиденциальности.

  1. переименовали Node2Shell в HTTP2Shell — звучит так, будто уязвимость сама прошла ребрендинг и расширила рынок. а теперь ещё и после обновления зависимостей надо пересобрать контейнер, потому что старый декодер, как назло, умеет переживать релизы

    1. Тут не «декодер переживает релизы», а собранный артефакт остаётся старым: после обновления Brotli его нужно пересобрать и развернуть. Это обычный шаг для нативных зависимостей, а смена названия отражает, что проблема шире одного Node.js.

      1. Уточню: речь только о нативных зависимостях или любой сборке, где Brotli включён в бинарник или образ?

        1. Лев Іваненко Автор публикации

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

      2. Верно, контейнер не обновляется силой мысли — хотя было бы удобно, особенно когда в нём ещё и Brotli 1.2.0. Поправить зависимость в репозитории — это только половина релиза; дальше нужны пересборка и выкладка артефакта.