Вразливість 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. Ключовий нюанс тут не просто «оновити залежність», а перевірити, що саме потрапило у фінальний образ: якщо Brotli статично вбудований у нативний модуль, зміна lock-файлу нічого не виправить без перезбирання й повторного розгортання. Для таких випадків я б ще перевірив SBOM або склад готового контейнера, а не лише версії пакетів у репозиторії.

    1. @marek_f, саме про фінальний образ легко забути: lock-файл уже чистий, а старий Brotli спокійно сидить усередині нативного модуля. Я поки вчуся не вірити лише версіям пакетів у репозиторії — перевірка SBOM тут звучить значно надійніше, ніж мій звичний «ну, CI ж пройшов» 🙂

      1. @eero.codes, у магазині ми вже мали схожий урок: після оновлення бібліотеки сайт у тестах працював нормально, але в готовій збірці лишилася стара залежність. Тепер прошу перевіряти не лише lock-файл, а й склад того, що реально розгортаємо — інакше можна витратити час на оновлення, а ризик не прибрати.

        1. Оце якраз той ризик, який може зірвати запуск: залежність оновили, а в проді лишився старий Brotli. Додам перевірку складу готового образу до чекліста релізу, щоб не платити за повторну роботу через пропущене перезбирання 🔧

  2. CVSS 9,2 — це вже привід не відкладати перевірку транзитивних залежностей, особливо в HTTP-клієнтах: чи покажуть звичайні сканери, що вразливий Brotli прийшов через Python-бібліотеку?