Критична дупка в Brotli: Node.js, Bun и Python

Уязвимост в Brotli декодера на Google засяга всяка програма, която декомпресира Brotli данни — а това е огромна част от съвременния веб. Пропускът носи номер CVE-2026-111497, получи оценка 9.2 по CVSS 4.0 от Google и беше оповестен публично на 21 октомври 2026 г. Засегнати са Node.js, Bun, Envoy, Istio, Python модулите Brotli и brotlicffi, както и инструментът cdxgen. Подготвени компресирани данни могат да презапишат памет извън предвидения буфер и да доведат до срив, изтичане на памет или изпълнение на код, избран от нападателя.
Пропускът е открит от Khai Tran и Sylvie Mayer от екипа Codex Security на OpenAI, а The Hacker News описа подробно обхвата му. Самата библиотека е уязвима във версии от 1.0.3 до 1.2.0 включително; поправени са 1.0.10, 1.1.1 и 1.2.1.
Къде точно се чупи декодерът
Проблемът е в стрийминг режима на декодера. Когато потокът съдържа смяна на блок, която форматът не допуска, декодерът връща „трябват ми още входни байтове“ вместо постоянна грешка във формата. Понеже заявката е временна, а не фатална, декодерът продължава да дописва входни байтове в един вътрешен буфер от осем байта — и излиза извън него.
Оттук следва класически out-of-bounds запис. Google класифицира пропуска като критичен, Node.js му дава степен High, а Red Hat го оценява на 8.1 (Important) — разликата идва от допускането колко лесно нападателят подава данните, които приложението ще декомпресира.
В Node.js отговорът е „много лесно“. Декодерът се достига директно през node:zlib, но и напълно автоматично — когато вграденият fetch() получи отговор със заглавка Content-Encoding: br, или когато middleware декомпресира Brotli тяло на входяща заявка.
# проверка кои линии са закърпени
node -v # трябва 22.23.4, 24.22.1 или 26.12.1 нагоре
bun -v # трябва 1.4.4 нагоре
Какво да ъпдейтнете
Списъкът е дълъг, защото Brotli обикновено се компилира вътре в други програми, а не се инсталира отделно:
- Node.js — уязвими са линиите 22.x, 24.x и 26.x; поправени са 22.23.4, 24.22.1 и 26.12.1. Линията 20.x е в края на живота си и няма да получи поправка. Изданието от 21 октомври затваря общо десет CVE-та, включително два заобикаляни проверки на име на хост в TLS сертификат.
- Bun — всичко до 1.4.3 включително; поправено в 1.4.4.
- Envoy — 1.39.2, 1.38.5, 1.37.7 и 1.36.11; поправени са 1.40.0, 1.39.3, 1.38.6, 1.37.8 и 1.36.12.
- Istio — 1.31.0–1.31.1, 1.30.0–1.30.5 и 1.29.0–1.29.8; поправени са 1.31.2, 1.30.6 и 1.29.9.
- Python — пакетът
Brotliдо 1.2.0 (поправен в 1.2.1) иbrotlicffiдо 1.2.0.x (поправен в 1.2.1.0). - cdxgen — 13.4.0 и 12.8.8 надолу; поправени са 13.5.0 и 12.8.9.
Ако държите Envoy или Istio пред Node.js приложения, ъпдейтът на двата слоя е отделна работа — и двата декомпресират сами.
Поправката е от февруари, но никой не е знаел защо
Най-неудобният детайл в цялата история е хронологията. Коренът на проблема е бил отстранен в кода на Brotli още на 27 февруари — като обикновен бъг. Тогава не е било ясно, че от него произлиза уязвимост в сигурността, а нова версия на Brotli не е излизала след това. Така поправката е седяла в main клона осем месеца, докато дистрибуциите и вградените копия са продължили да ползват стария код.
Това е честият сценарий при библиотеки, които се vendor-ват: поправката съществува, но не стига до никого, защото няма release, който да я носи.
Засега няма данни за експлоатация в реални атаки. Публичен proof-of-concept има само за Node.js — демонстрацията, известна като Node2Shell, за която писахме покрай критичния пропуск в Pillow. CISA оценява вероятността за експлоатация като „none“, а автоматизацията — като „no“.
Втори фронт: трети бъг в PHP
Същата седмица PHP мина през подобно упражнение. След двете RCE дупки от 21 октомври (CVE-2026-109618 и CVE-2026-109619) в петък се появи и трета — CVE-2026-115560. Тя обаче няма да получи извънредна кръпка, а ще влезе в следващото редовно bugfix издание, пише The Register.
Причината е, че условията са екзотични: session.serialize_handler трябва да е php_binary или php_serialize, после да бъде сменен на php през ini_set() преди session_start(), при включен session upload progress. Препоръката на PHP Foundation дотогава е една линия:
session.upload_progress.enabled=0
Изпълнителният директор на фондацията Elizabeth Barron казва, че няма данни за успешна експлоатация върху закърпени системи, докато CTO на Mandiant Charles Carmakal предупреждава, че „експлоатацията може вече да е започнала в ограничен вид“.
Заключение
Brotli не е продукт, който инсталирате — той е част от HTTP стека ви, компилиран вътре в runtime или в reverse proxy. Затова и въпросът „уязвими ли сме“ тук не се свежда до един apt upgrade, а до инвентар: кои процеси декомпресират Brotli и от коя версия идва кодът им. Ако декомпресирате данни от външни източници — през fetch(), през middleware или през sidecar — ъпдейтът е за днес. Останалото е обичайната сметка: половин час поддръжка срещу out-of-bounds запис в памет, който вече има работещ PoC.
Харесва ви? Отбележете ни и ще ни виждате по-нагоре в Google.
Предпочитан източник в Google