OpenAI нашла в Brotli дыру с удалённым выполнением кода

Кхай Тран и Сильви Майер из OpenAI Codex Security нашли в декодере Brotli уязвимость CVE-2026-111497: поддельный сжатый поток портит память и, по описанию OpenAI, даёт выполнить код без всякой авторизации. Исправленные версии Node.js, Bun, Envoy, Istio и самой библиотеки, а также обходные меры собраны на странице Patch the Planet, которую последний раз обновили 23 октября.
Сама ошибка описана в бюллетене Node.js одной фразой. Невалидное переключение блока декодер сообщал как временную нехватку входных данных вместо окончательной ошибки формата, и потоковый декодер продолжал дописывать байты во внутренний буфер размером восемь байт.
Восемь байт буфера
Brotli - библиотека сжатия от Google, которую встраивают в рантаймы, прокси и клиенты. Node.js держит её копию в модуле zlib и запускает этот код при любой распаковке Brotli: напрямую через node:zlib или автоматически, когда fetch() получает ответ с таким сжатием. Запись за пределы буфера возникает на некорректном потоке, а исправление из апстрима заставляет декодер распознать битые данные и остановиться раньше.
В OpenAI описывают обе стороны атаки:
Сервер без патча, который принимает сжатые данные, может захватить злонамеренный клиент, а клиент без патча, который принимает сжатые данные (например, «curl --compressed»), может захватить злонамеренный сервер.
Под угрозой любое приложение, которое отдаёт данные атакующего уязвимому декодеру Google Brotli: сжатые тела HTTP-запросов, ответы с недоверенных серверов, сжатые файлы. Последствия, по Patch the Planet, бывают трёх видов: падение, утечка памяти или выполнение кода. Проверять советуют веб-сервисы, фоновые воркеры, инструменты со встроенным Node.js или Bun, а также прокси Envoy и Istio, где включена распаковка Brotli.
Список на этом не заканчивается. В десктопных приложениях на Electron бывает несколько копий Brotli, и исправленный Chromium ничего не говорит о встроенном Node.js. Отдельно нужно смотреть, какой декодер грузят curl и libcurl, привязки для Python и Java, другие нативные библиотеки; готовые wheels и статические бинарники могут требовать своего обновления или пересборки. Brotli читают и декодеры шрифтов, и читалки файлов данных, так что дело не ограничивается HTTP. Если же сервис только сжимает свои ответы в Brotli и ничего чужого не распаковывает, сама по себе эта уязвимость его не касается.
Февральский фикс без релиза
По словам OpenAI, корневую ошибку в исходниках Brotli исправили ещё в феврале, но тогда никто не понял, что она даёт уязвимость, а нового релиза библиотеки с тех пор не выходило. Поскольку Brotli встроен в чужие программы, обновление должны подхватить сначала они, а потом их пользователи. OpenAI сообщила об уязвимости мейнтейнерам Brotli и проектам ниже по цепочке, после чего Brotli выпустил версии 1.0.10, 1.1.1 и 1.2.1 и опубликовал CVE. Patch the Planet - та же инициатива OpenAI, участники которой в октябре нашли критические уязвимости в PHP.
Node.js выпустил исправления 21 октября сразу для трёх веток: 22.23.4, 24.22.1 и 26.12.1. В тот же выпуск вошли ещё девять уязвимостей. Высокий рейтинг из всех десяти у четырёх: у Brotli и у трёх ошибок обработки имён хостов в TLS и DNS. Ветка 20.x и более ранние закончили поддержку 30 апреля и патча не получат. Патч в бюллетене Node.js приписан mcollina и aduh95, то есть Маттео Коллине и Антуану дю Амелю.
Bun закрыл дыру в версии 1.4.4, куда вошёл Brotli 1.2.1. У Envoy исправлены 1.40.0, 1.39.3, 1.38.6 и 1.37.8; фикс есть и в 1.36.12, но ветка 1.36 не поддерживается. У Istio это 1.29.9, 1.30.6 и 1.31.2, причём 1.29 уже снята с поддержки, и Patch the Planet советует перейти на живую ветку.
Critical, high или medium
Одну и ту же ошибку оценивают по-разному. В записи CVE, которую ведёт Google, стоит 9,2 по CVSS 4.0 с уровнем Critical: атака по сети, без привилегий и без участия пользователя, с высоким ущербом для конфиденциальности, целостности и доступности. Node.js в своём бюллетене ставит «high», Ubuntu - «Medium», а NVD держит запись в статусе «Awaiting Analysis». В бюллетене Istio рядом с CVE стоит оценка 7,7, но, как мы выяснили, она относится к собственной ошибке Istio с падением istiod, а не к Brotli.
Насколько реальна атака, пока известно со слов The Hacker News. Издание сообщает, что публичный proof-of-concept появился 22 октября и довёл дело до выполнения кода только на намеренно ослабленной тестовой сборке. На стандартной сборке Node.js автор, по его словам, получил падение процесса и ограниченное чтение памяти. Об эксплуатации в реальных атаках на 22 октября там не сообщалось.
Авторский разбор
Что мы проверили
24 октября мы прошли по истории git Brotli, Envoy, Istio и Node.js и открыли запись CVE, трекеры безопасности Debian и Ubuntu и страницы пакетов на PyPI.
Рассказ OpenAI о тихом февральском фиксе подтвердился, но ошибка гораздо старше, а до пользователей исправление дошло не одним днём. OpenAI говорит, что релиза с фиксом не было, но пользователи Envoy получили его за две недели до релизов Brotli, просто под видом обновления зависимости. А тем, кто проверяет Node.js по номеру встроенной библиотеки, этот номер ничего не скажет.
- Уязвимый код появился 26 февраля 2018 года в коммите «Large Window Brotli» и впервые вышел в v1.0.3 от 2 марта 2018 года; диапазон уязвимых версий в записи CVE начинается ровно с 1.0.3. В релизах ошибка прожила около восьми с половиной лет.
- Фикс Евгения Ключникова датирован 27 февраля 2026 года, три исправленных тега - 21 октября, через 236 дней. Ни один тег не собран из master: каждый представляет собой старый релиз плюс один перенесённый коммит. Ту же дату, 27 февраля, Google проставил в записи CVE как дату публичного раскрытия.
- Envoy 6 октября (1.39.3, 1.38.6, 1.37.8, 1.36.12) и 13 октября (1.40.0) перевёл Brotli с тега 1.2.0 на коммит master от 30 сентября, где фикс уже был. Коммит называется «[v1.39] Update brotli to 42a2ed4», в описаниях пяти релизов Brotli не упоминается. До релизов Brotli оставалось 15 дней, до публикации CVE 22 октября - 16.
- Бюллетень Istio ISTIO-SECURITY-2026-007 от 15 октября уже называет CVE-2026-111497, за неделю до публикации записи. Версии 1.29.9 и 1.30.6 вышли 15 октября, 1.31.2 - днём позже; поддержка 1.29 закончилась 15 октября, в день выхода её последней исправленной сборки.
- Node.js не переходил на Brotli 1.2.1, а перенёс коммит в свою копию: 22.x по-прежнему сообщает Brotli 1.1.0, 24.x и 26.x - 1.2.0. Команда
node -p process.versions.brotliпатченную сборку от старой не отличит; фикс есть в 22.23.4, 24.22.1 и 26.12.1 и отсутствует в 22.23.3, 24.22.0 и 26.12.0.
Как закрыться до обновления
Если патч поставить нельзя сразу, Patch the Planet советует отключить распаковку Brotli для недоверенных данных на каждом пути декодирования, оставив gzip, deflate и другие кодеки. Входящие запросы с Content-Encoding: br нужно отклонять раньше, чем их распакует прокси, middleware или парсер тела, включая обходные маршруты прямо на origin. Отключение сжатия ответов на CDN или веб-сервере распаковку на стороне запросов и клиентов не трогает, а лимиты на размер запроса и правила WAF закрывают не все пути. Убрать br из Accept-Encoding тоже мало: сервер может прислать Brotli и так.
Для Express предлагается middleware, которое ставят перед всеми парсерами тела и пропускает только identity, gzip и deflate, а всё остальное, включая составные кодировки вроде gzip, br, отклоняет с кодом 415. Запасной вариант - inflate: false на каждом парсере, но он отсечёт и gzip с deflate. В Next.js без обновлённого Node.js рекомендуют глобально выставить images.unoptimized: true, пересобрать проект и убедиться, что запросы к /_next/image больше не идут через оптимизатор; от других серверных fetch и собственных загрузчиков картинок это не защищает.
В Envoy убирают HTTP-фильтр распаковки с типом Brotli или выключают в нём оба направления, запросы и ответы, сохраняя отдельные фильтры gzip и zstd. Из полей enabled нужно убрать runtime_key, иначе runtime-переопределение может вернуть Brotli, а неуказанное направление по умолчанию включено. В Istio правят исходный патч EnvoyFilter, который вставляет Brotli-фильтр, но не удаляют все фильтры с именем envoy.filters.http.decompressor: под ним могут жить и gzip, и zstd. Выключенный фильтр пропускает сжатые байты дальше, поэтому Brotli надо отклонять до любого уязвимого декодера ниже по цепочке.
Для Python-клиента на urllib3 пример строится на preload_content=False и decode_content=False: тело не читается, пока не проверен заголовок кодировки, а редиректы и повторы выключены, чтобы проверку проходил каждый ответ. Проверять заголовки после обычного fetch() или автоматического чтения тела может быть уже поздно. Сами привязки обновились: мы нашли на PyPI wheels Brotli 1.2.1 и brotlicffi 1.2.1.0, загруженные 22 октября, а Bun 1.4.4 вышел в тот же день с переходом на тег v1.2.1.
Node.js из пакетов Debian и Ubuntu собран с системной libbrotli вместо встроенной копии, поэтому исправление приходит через пакет brotli дистрибутива; официальные бинарники, nvm, NodeSource и Docker-образы несут свою копию. На 24 октября, по трекеру Debian, brotli исправлен в trixie-security (1.1.0-2+deb13u1, DSA-6582-1 от 23 октября) и bookworm-security (1.0.9-2+deb12u1, DLA-4855-1), а в sid и forky версия 1.2.0-4 остаётся уязвимой. В Ubuntu все релизы brotli и nodejs пока в статусе «Needs evaluation».
После обновления Patch the Planet просит поднять пины рантаймов и образов, пересобрать контейнеры и исполняемые файлы со встроенным рантаймом и перезапустить каждый сервис, воркер, задачу по расписанию и реплику на старой сборке. Затем остаётся сверить запущенный бинарник или образ со списком исправленных релизов и убедиться, что временный запрет отклоняет Brotli до декодирования, а разрешённый gzip по-прежнему работает.
Дальше
В Grok Bot заметили хранилище для паролей и карт, Видео
Судя по посту в Threads, Grok Bot от xAI получил собственное хранилище для логинов, контактов и данных банковских карт. Вкладка Vault появляется в настройках мобильного и десктопного приложений. Пароли от сервисов вы бы доверили хранилищу чат-бота или только менеджеру паролей?
Читайте также
- OpenAI выложила проверку сайтов на уязвимость php2shell
- Cloudflare ищет уязвимости клиентов моделями OpenAI
- Модели OpenAI помогли найти критические уязвимости в PHP
- Битая картинка могла вскрыть Slack, Meta и GitHub
- Агенты OpenAI ломали RubyGems дырой, найденной в июле
- Fraggap: через баг ядра Linux агенты OpenAI взяли root
Комментарии
Пока никто не написал. Будьте первым.
Присоединяйтесь к разговору
Войдите, чтобы оставить комментарий. Он появится после модерации.

