Podatność Brotli w Node.js, CVE-2026-111497: wersje i co zrobić

Cyber Katalog 22 min czytania Alert Podatności
TL;DR

CVE-2026-111497 to zapis poza buforem w dekoderze Brotli, przez który spreparowany strumień danych może uszkodzić pamięć procesu i potencjalnie doprowadzić do zdalnego wykonania kodu bez uwierzytelnienia1. Node.js usunął błąd 21 października 2026 roku w wersjach 22.23.4, 24.22.1 i 26.12.12, a komunikat nie podaje żadnego obejścia poza aktualizacją2. GitHub ocenia lukę na 9,2 w skali CVSS 4.01, natomiast Node.js w swoim komunikacie określa ją jako wysoką2. Ryzyko dotyczy każdego programu z niezałataną kopią dekodera Brotli, który rozpakowuje dane spoza własnej kontroli, także gdy robi to za niego zależność, więc obejmuje również Buna, Pythona, bibliotekę Brotli4j w Javie, curl i Envoya, a w .NET pozostaje pytaniem bez odpowiedzi.

Luka leży w kodzie Brotli, który napisało Google, a nie w samym Node.js, więc każde środowisko, które dołączyło tę bibliotekę, ma własną kopię dekodera, własny termin poprawki i własny sposób jej wdrożenia. Aktualizacja Node.js zamyka sprawę tylko tam, gdzie dekoder pochodzi z Node.js.

Co się stało: Brotli i Node.js w skrócie

21 października 2026 roku o godz. 10:38 UTC, czyli o 12:38 czasu polskiego, Node.js opublikował wydania 22.23.4, 24.22.1 i 26.12.13. Zamykają one 10 podatności, a CVE-2026-111497 dotyczy gałęzi 26.x, 24.x i 22.x2. Ten identyfikator CVE odnosi się do dekodera Brotli w pliku c/dec/decode.c, w wersjach od 1.0.3 do 1.2.0 na wszystkich platformach, a poprawione wydania biblioteki to 1.0.10, 1.1.1 i 1.2.11.

Według Node.js nieprawidłowe przełączenie bloku było zgłaszane jako chwilowa potrzeba dalszych danych zamiast trwałego błędu formatu, więc strumieniowy dekoder dalej dopisywał bajty wejścia do wewnętrznego bufora o rozmiarze ośmiu bajtów2. Atakujący, który dostarczy dane Brotli rozpakowywane przez aplikację w node:zlib, może w ten sposób uszkodzić pamięć procesu, co może skończyć się awarią, ujawnieniem pamięci albo zdalnym wykonaniem kodu2. W poprawce funkcja DecodeBlockTypeAndLength zwraca kod błędu zamiast wartości logicznej, a dla niedozwolonego przełączenia bloku zgłasza nowy błąd BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH o kodzie -174.

Ta zmiana trafiła do repozytorium Brotli 27 lutego 2026 roku z opisem "Detect and report invalid stream earlier." i bez wzmianki o bezpieczeństwie4, a wydania z numerem CVE ukazały się dopiero 21 października około 19:27 UTC567. Poprawka czekała więc na wydanie prawie osiem miesięcy.

GitHub Advisory Database ocenia lukę jako krytyczną, na 9,2 w skali CVSS 4.0, z wektorem sieciowym, bez wymaganych uprawnień i bez udziału użytkownika, oraz z klasyfikacją CWE-2521, a Node.js ocenia tę samą lukę jako "High", czyli wysoką2. Lukę zgłosił zespół OpenAI Codex Security, a poprawkę w Node.js przygotowali mcollina i aduh952. Aikido, powołując się na The Hacker News, podaje, że do 22 października nie zgłoszono wykorzystania tej luki w atakach na Node.js8.

Nazwy w obiegu: Node2Shell, HTTP2Shell, Broccoli2Shell

Node.js w swoim komunikacie nie używa żadnej z trzech nazw2. Node2Shell stoi w tytule analizy Impervy9 i w advisory GitHub1. HTTP2Shell występuje w tytule wpisu Aikido, który pisze, że Node2Shell "evolves to HTTP2Shell", ponieważ błąd dotyczy bibliotek i aplikacji używających HTTP8. Broccoli2Shell występuje w adresie broccoli2shell.com, który zgłoszenie w repozytorium gemu Ruby podaje jako przegląd dotkniętego oprogramowania10.

Skoro w obiegu są trzy nazwy, a żadna nie jest oficjalna, do wyszukiwania w inwentarzu, skanerze i advisory dostawców nadaje się numer: CVE-2026-111497. Imperva zestawia Node2Shell z PHP2Shell jako pokrewne badania i pisze, że sztuczna inteligencja może przyspieszać zarówno odkrywanie podatności, jak i tworzenie exploitów9.

Dlaczego dekompresja jest powierzchnią ataku

Dekoder pracuje na bajtach, które przysłał ktoś inny, i robi to w kodzie napisanym w C, więc błąd w nim nie wymaga żadnej pomyłki po stronie programisty aplikacji.

Kto dostarcza strumień

Strumień Brotli może wejść do programu trzema drogami. Pierwsza to odpowiedź zdalnego serwera: wbudowane fetch() w Node.js dekoduje odpowiedź z nagłówkiem Content-Encoding: br9, a Bun robi to domyślnie przy każdej takiej odpowiedzi11. Druga to ciało żądania, które serwer rozpakowuje, zanim przekaże je aplikacji: Express 5 z zamontowanym parserem ciała (express.json(), express.raw() i pokrewne, oparte na body-parser 2) dekoduje Brotli, bo obsługa pochodzi z wersji 2.0.0 tego pakietu12, a opcja inflate jest domyślnie włączona13. Trzecia to wgrany albo pobrany plik ze strumieniami Brotli, który parsuje biblioteka, jak w Brotli4j14. Zwykły serwer node:http nie dekoduje sam przychodzących ciał Brotli, więc potrzebny jest middleware albo własny kod, który to robi9.

Po stronie Pythona klientami narażonymi na odpowiedzi z cudzych serwerów są urllib3 i requests (gdy zainstalowano Brotli albo brotlicffi), httpx z dodatkiem brotli, aiohttp i Scrapy, a typowe scenariusze to webhooki, podglądy adresów i crawlery15. Ci klienci korzystają z zainstalowanego pakietu automatycznie, bez żadnego importu w kodzie aplikacji15.

Co potwierdzono w Node.js

Imperva wykonała w aplikacji kod przesłany w spreparowanych danych Brotli na oficjalnym obrazie Node.js 24.22.0 dla Linuksa arm64, w świeżych kontenerach, a wersja 24.22.1 odrzuciła te same dane. Wykonanie kodu wymagało kilku prób, a kod uruchomił się z express.raw() i express.json() na Express 5.0.0 (body-parser 2.0.1) i 5.3.0 (body-parser 2.3.0) oraz z samym body-parser 2.0.0. Test objął ten jeden build, funkcję fetch() i wymienione wersje Express 5 oraz body-parser 2, a nie objął innych architektur, gałęzi 22.x i 26.x ani Express 4 i body-parser 1.x9.

Dlaczego zależności też

Rozpakowanie dzieje się w bibliotece, zanim aplikacja dostanie treść, więc logowanie, uwierzytelnianie i trasy nie zatrzymają błędu, a odciąć go można tylko przed dekoderem. Dekoder rozpakowuje dane, zanim kod aplikacji, w tym logowanie i kontrola uprawnień, zobaczy ich treść, a według GitHub Advisory Database atakujący nie musi być uwierzytelniony1. Ten sam układ pokazuje osobna luka body-parser, CVE-2026-111181, opublikowana 22 października i oceniona jako wysoka w GitHub Advisory Database. Pojedyncze żądanie ze skompresowanym ciałem i dodatkowymi bajtami po ramce może przerwać proces, a nie jest potrzebne ani uwierzytelnienie, ani pasująca trasa, bo parsowanie działa przed routingiem16. Poprawka jest w body-parser 2.4.0 i 1.20.9, a obejściem jest inflate: false1612.

W Brotli4j bezpieczeństwo pamięci Javy niczego nie zmienia, bo dekoder działa w kodzie natywnym przez JNI14.

Droga strumienia Brotli: serwer lub użytkownik wysyła dane z Content-Encoding br albo plik, natywny dekoder w bibliotece rozpakowuje je i może zapisać poza buforem, dopiero potem treść trafia do kodu aplikacji z logowaniem i uprawnieniami
Błąd działa na etapie dekodera, więc kontrola, którą aplikacja wykonuje na treści, następuje już po jego zadziałaniu

Czy mnie to dotyczy: stan środowisk na 24 października 2026

O tym, czy aktualizacja jednego pakietu wystarczy, decyduje to, skąd środowisko bierze dekoder. Node.js, Bun i .NET mają własną kopię w samym środowisku uruchomieniowym, a Python, Brotli4j, gem Ruby i rozszerzenie PHP dołączają ją w pakiecie. Node.js z Debiana korzysta z biblioteki systemowej, a Go i Java mają też własne porty dekodera napisane w tych językach, więc w każdym z tych przypadków aktualizuje się coś innego.

Środowisko Skąd dekoder Stan na 24.10.2026
Node.js z oficjalnych wydań Własna kopia w deps/brotli Poprawione w 22.23.4, 24.22.1 i 26.12.1217
Node.js z pakietu Debiana Systemowa biblioteka brotli Poprawka w pakiecie brotli: bookworm 1.0.9-2+deb12u1, trixie 1.1.0-2+deb13u1; forky i sid bez poprawki18
Bun Własna kopia: do 1.4.2 Brotli 1.1.0, potem 1.2.0 Poprawione w 1.4.4 z 22.101119
Python: Brotli i brotlicffi Dekoder w pakiecie Poprawione w Brotli 1.2.1 i brotlicffi 1.2.1.01
Java: Brotli4j Własny natywny build w artefaktach native-* Poprawione w 1.24.0 z 24.1014
Java: org.brotli:dec Dekoder napisany w Javie Żadne advisory z tej tabeli nie obejmuje tego dekodera; wydanie 1.2.1 go nie zmienia, poprawka dotyczy kodu w C20
.NET Własna kopia Brotli 1.1.0 Kod sprzed poprawki, bez odpowiedzi zespołu w zgłoszeniu w dotnet/runtime212223
PHP: rozszerzenie php-ext-brotli Brotli jako submoduł rozszerzenia Poprawka w otwartym PR #10524
Ruby: gem brotli Dołączony Brotli 1.2.0, budowany, gdy brak systemowego 1.2.0 lub nowszego Poprawione w 0.9.1 z 24.1025
Go: andybalholm/brotli Port napisany w Go Poprawione w v1.2.726
curl i libcurl Zależność Brotli, czasem dołączona statycznie Aktualizacja zależności do Brotli 1.2.1, starszej poprawionej linii albo pakietu dostawcy; kopie dołączone statycznie wymagają przebudowy aplikacji8
Envoy Dekompresor Brotli w konfiguracji Poprawione w v1.40.0, 1.39.3, 1.38.6, 1.37.8 i 1.36.1227
Istio Envoy w warstwie sieciowej Poprawione w 1.29.9, 1.30.6 i 1.31.2; gałąź 1.29 bez wsparcia8
Cztery źródła dekodera Brotli: własna kopia w runtime (Node.js, Bun, .NET), kopia w pakiecie (Python, Brotli4j, gem Ruby, rozszerzenie PHP), biblioteka systemowa (Node.js z Debiana) i port w innym języku (dekoder w Javie bez advisory, port w Go z poprawką v1.2.7), każde z innym sposobem aktualizacji
Poprawka biblioteki nadrzędnej nie dociera do kopii, którą ktoś dołączył do własnego pakietu, dopóki jego autor nie wyda aktualizacji

Bun

Bun do wersji 1.4.2 buduje Brotli 1.1.0, a wersja 1.4.3 i gałąź główna budowały 1.2.0, w obu przypadkach bez własnych łatek. Do dekodera prowadzą fetch() przy każdej odpowiedzi z Content-Encoding: br, node:zlib i DecompressionStream("brotli"), a zgłoszenie w repozytorium Buna pochodzi z 21 października11. Poprawkę, czyli aktualizację Brotli, scalono 22 października o 02:13 UTC28, a Bun 1.4.4 z tego dnia wymienia Brotli wśród dotkniętych protokołów i API w sekcji bezpieczeństwa19. Pliki wykonywalne skompilowane Bunem trzeba według Aikido zbudować ponownie8.

Python

Pakiety PyPI Brotli (rozszerzenie CPython od Google) i brotlicffi (wersja CFFI, używana między innymi w PyPy) kompilują podatny dekoder15. Advisory obejmuje Brotli od 1.0.3 do wersji niższej niż 1.2.1 oraz brotlicffi od 1.0.3 do wersji niższej niż 1.2.1.0, a poprawione są Brotli 1.2.1 i brotlicffi 1.2.1.0; advisory zaktualizowano 23 października i obejmuje oba pakiety PyPI1. OpenSourceMalware sprawdziło też starsze wydania Brotli z PyPI, aż do 0.5.2, i w każdym znalazło ten sam brak zgłaszania nieprawidłowego przełączenia bloku, więc cofnięcie się do starszej wersji nie jest wyjściem15.

OpenSourceMalware zbudowało Brotli 1.2.0 z AddressSanitizer: dekoder przyjął spreparowany strumień o rozmiarze około 23 MB i zwrócił NEEDS_MORE_INPUT, a wersja 1.2.1 odrzuciła go błędem -17. Wykonania kodu w Pythonie OpenSourceMalware nie próbowało15.

Java: Brotli4j

Brotli4j dołącza własny natywny build Brotli w C. Każde wydanie do 1.23.0 włącznie zawiera dekoder z Brotli 1.0.9, 1.1.0 albo 1.2.0, a wszystkie trzy mają CVE-2026-111497. Narażone ścieżki to Decoder, DirectDecompress, BrotliInputStream, BrotliDecoderChannel i DecoderJNI, typowe punkty wejścia to serwery i klienci HTTP z Content-Encoding: br przez Netty albo Apache HttpClient oraz parsowanie niezaufanych plików, a koder nie jest dotknięty14. Aktualizacja systemowego libbrotli nic tu nie daje, bo Brotli4j ładuje kopię z artefaktów native-*14. Poprawka to Brotli4j 1.24.0 z 24 października, który synchronizuje dołączone źródła z Brotli 1.2.1, więc podnieść trzeba zarówno brotli4j, jak i każdy artefakt native-* oraz BOM14.

Dekoder napisany w samej Javie, org.brotli:dec, to inny kod. Wydanie Brotli 1.2.1 to dwa commity i cztery zmienione pliki20: poprawka z lutego, która zmienia wyłącznie c/dec/decode.c i c/include/brotli/decode.h4, oraz przygotowanie wydania, które zmienia CHANGELOG.md i c/common/version.h29. Ani dekoder w Javie, ani porty w innych językach nie dostały w tym wydaniu żadnej zmiany, choć port w Go dostał własną poprawkę w v1.2.7, bo miał ten sam wzorzec. Żadne advisory z tabeli wyżej nie obejmuje dekodera org.brotli:dec, więc dla niego nie ma ani poprawki, ani potwierdzenia, że błąd go dotyczy.

.NET: kopia z kodem sprzed poprawki

Środowisko uruchomieniowe .NET ma własną kopię Brotli 1.1.021. W wersji 10.0.13 funkcja DecodeBlockTypeAndLength ma jeszcze postać sprzed poprawki i zwraca wartość logiczną22, a autor zgłoszenia opisanego niżej wskazuje to samo w wersji 9.0.2123.

24 października w dotnet/runtime otwarto zgłoszenie z pytaniem, czy CVE dotyczy System.IO.Compression.Brotli w .NET 9.0.21 i 10.0.13. Autor wskazuje drogę przez BrotliDecompressionProvider w ASP.NET Core, który przy dekompresji ciał żądań tworzy BrotliStream wywołujący natywny dekoder, i zaznacza, że to analiza kodu, bez uruchomienia23. W tym zgłoszeniu zespół .NET nie odpowiedział jeszcze na pytanie, czy podatność dotyczy wersji 9.0.21 i 10.0.13, a dekoder w tych wersjach ma kod sprzed poprawki23, więc to stan wiedzy z 24 października, a nie potwierdzona luka.

PHP, Ruby, Go, curl, Envoy i Istio

PHP2Shell i ta luka to osobne sprawy. Rozszerzenie php-ext-brotli, które dekoduje Brotli w PHP, ma poprawkę CVE-2026-111497 w pull requeście #105, otwartym 22 października i niescalonym na 24 października24.

Gem brotli dołączał Brotli 1.2.0 i budował go, gdy nie znalazł systemowego libbrotli 1.2.0 lub nowszego, a Brotli.inflate przekazuje dane do dekodera. Dystrybucje zwykle wprowadzają poprawkę bez zmiany numeru wersji, więc sprawdzanie numeru nie jest tu wiarygodne10. Poprawka z 24 października wymusza Brotli 1.2.1 i odrzuca systemowe Brotli bez poprawki25. Zawiera ją gem 0.9.1, a wcześniejsza wersja 0.9.0 jeszcze nie30.

Port andybalholm/brotli w Go miał ten sam wzorzec, w którym wyniki decodeBlockTypeAndLength były ignorowane. Zgłaszający przypuszcza, że w Go skończy się to raczej panic niż uszkodzeniem pamięci, ale nie przedstawił reprodukcji31. Poprawka z 23 października jest w tagu v1.2.726.

Według Aikido curl i libcurl wymagają aktualizacji zależności Brotli do wersji 1.2.1, poprawionej starszej linii albo pakietu dostawcy z poprawką, a kopie dołączone do aplikacji albo skompilowane statycznie wymagają przebudowy tej aplikacji8. Apache ze standardowym modułem mod_brotli i nginx domyślnie nie dekodują Brotli, więc w domyślnej konfiguracji sam serwer WWW nie rozpakowuje przychodzących danych w tym formacie8.

W Envoyu podatne są v1.39.2, v1.38.5, v1.37.7 i v1.36.11, a dotyczy to wdrożeń ze skonfigurowanym dekompresorem Brotli. Advisory z 23 października ocenia lukę jako krytyczną i wskazuje na zgłoszenie od OpenAI Security Research27. Istio ma poprawkę w wersjach 1.29.9, 1.30.6 i 1.31.2, a gałąź 1.29 nie ma już wsparcia8.

Wersje Node.js z poprawką

Poprawione wydania to 22.23.4, 24.22.1 i 26.12.12. Wersje bez wsparcia są według komunikatu zawsze dotknięte, gdy ukazuje się wydanie bezpieczeństwa2, więc linie 20, 23 i 25, których wsparcie już się skończyło32, poprawki nie dostaną.

Linia Wersja z poprawką Stan wsparcia
26 26.12.1 Wchodzi w LTS 28.10.202632
24 24.22.1 Faza maintenance od 20.10.202632
22 22.23.4 Wsparcie do 30.04.202732
25 brak Koniec wsparcia 01.06.202632
20 brak Koniec wsparcia 30.04.202632
23 brak Koniec wsparcia 01.06.202532

Poprawione wydanie 24.22.1 ma w deps/brotli nadal numer Brotli 1.2.0, bo poprawkę naniesiono na dołączony kod bez zmiany numeru17. process.versions.brotli nie odróżnia więc wersji poprawionej od podatnej, liczy się wersja samego Node.js.

W Debianie pakiet nodejs korzysta z systemowej biblioteki brotli, więc poprawkę przynosi aktualizacja pakietu brotli, a nie samego Node.js18. Po aktualizacji biblioteki trzeba zrestartować procesy, które ją załadowały, bo działające procesy zachowują starą kopię w pamięci.

Co zrobić teraz

Kolejność jest taka: najpierw ustalić, gdzie działa dekoder Brotli, potem wdrożyć poprawkę tam, gdzie istnieje, a tam, gdzie jej nie ma, odciąć strumienie Brotli, zanim trafią do dekodera.

Trzy ścieżki działania: Node.js 22, 24 i 26 aktualizujemy do wersji z poprawką, restartujemy procesy i przebudowujemy obrazy, biblioteka bez poprawki wymaga odrzucania Content-Encoding br, inflate false, usunięcia br z Accept-Encoding i odrzucania odpowiedzi br, oficjalna linia bez wsparcia wymaga migracji, a Node.js z dystrybucji aktualizacji libbrotli, dla wszystkich zaś wspólny jest inwentarz i sprawdzenie śladów
Aktualizacja, odcięcie Brotli i migracja to trzy odpowiedzi na ten sam błąd, a inwentarz i ślady trzeba sprawdzić w każdej z nich

1. Ustal, gdzie działa dekoder Brotli

Inwentarz samych aplikacji i interpreterów, jaki był potrzebny przy PHP2Shell, tutaj nie wystarcza, bo Brotli bywa zależnością zależności, a według Impervy inwentarze pakietów mogą pominąć wbudowane środowiska uruchomieniowe9. Zasada ustalania kolejności jest ta sama co w zarządzaniu podatnościami: najpierw systemy dostępne z internetu i te, które przyjmują albo pobierają dane spoza organizacji.

Wersję Node.js sprawdza się na hostach i wewnątrz obrazów kontenerów9:

node -v
docker run --rm --entrypoint node <obraz> -v
pip show Brotli brotlicffi

Ostatnia komenda dotyczy Pythona15. W Javie wystarczy przejrzeć drzewo zależności, na przykład przez mvn dependency:tree albo gradle dependencies, pod kątem com.aayushatharva.brotli4j14. Dla Node.js z dystrybucji liczy się wersja pakietu brotli w menedżerze pakietów18. Kolejne podatności w komponentach z takiego spisu zbiera rejestr nowych podatności, z którym spis da się porównywać na bieżąco.

2. Zaktualizuj środowiska z poprawką i zrestartuj procesy

Po aktualizacji trzeba zrestartować procesy, a obrazy kontenerów przebudować i wdrożyć ponownie, bo runtime jest częścią obrazu. Poprawka wymaga Node.js 22.23.4, 24.22.1 albo 26.12.1, a komunikat nie przewiduje obejścia2. Pliki wykonywalne skompilowane Bunem buduje się od nowa8. W Envoyu wystarczy aktualizacja do wersji z tabeli, a luka dotyczy wdrożeń ze skonfigurowanym dekompresorem Brotli27. Wersje z poprawką dla Buna, Pythona, Brotli4j, gemu Ruby, Go, curl, Envoya i Istio wymienia tabela wyżej.

3. Tam, gdzie poprawki nie ma, odrzucaj Brotli przed dekoderem

Dla środowisk, których nie da się zaktualizować od razu, kierunek jest jeden: dane w Brotli nie powinny dochodzić do dekodera, jeśli aplikacja ich nie potrzebuje.

W Pythonie OpenSourceMalware wskazuje dwa sposoby. Pierwszy to odinstalowanie pakietów Brotli i brotlicffi, po czym klienci HTTP wracają do gzip i deflate, choć według Aikido serwer, który mimo to wyśle Brotli, może wtedy wywołać błąd aplikacji, bo automatyczny powrót nie jest gwarantowany8. Drugi to usunięcie br z wychodzącego Accept-Encoding i odrzucanie przychodzących Content-Encoding: br15. Aikido zaznacza, że sama zmiana Accept-Encoding nie wystarcza, bo trzeba też odrzucać odpowiedzi z br przed dekodowaniem8. W Express 5 oficjalnym sposobem odrzucenia skompresowanych ciał, w tym gzip i deflate, jest inflate: false13.

W samej bibliotece Brotli4j obejścia nie ma. Do czasu aktualizacji nie należy więc dekompresować danych z niezaufanych źródeł, a w stosach HTTP trzeba usunąć br z akceptowanych Content-Encoding14. W .NET, do czasu odpowiedzi zespołu .NET, ten sam kierunek ma sens tam, gdzie ASP.NET Core nie musi przyjmować ciał w Brotli: odrzucanie ich na wejściu.

4. Linie bez wsparcia: zaplanuj migrację

Node.js 20, 23 i 25 nie dostały wydania, a wersje bez wsparcia są według komunikatu zawsze dotknięte2. Dla oficjalnych wydań Node.js 20, 23 i 25 jedyną drogą do poprawki jest przejście na linię 22, 24 albo 26. Node.js z pakietu dystrybucji, który korzysta z systemowej biblioteki brotli, jak w Debianie, dostaje poprawkę razem z aktualizacją tej biblioteki18. Linia 22 ma wsparcie do 30 kwietnia 2027 roku32, więc dla nowych wdrożeń lepsza jest 24 albo 26.

5. Skanerowi zależności nie ufaj bez sprawdzenia

Według Aikido do 23 października pip-audit, Dependabot i Safety nie oznaczały podatnych wersji pakietów Pythona, bo bazy advisory nie wiązały jeszcze tego CVE z pakietami PyPI8. Advisory w GitHub Advisory Database zaktualizowano 23 października o 19:08 UTC i obejmuje ono oba pakiety1, więc ten stan mógł się już zmienić, ale brak alertu w skanerze nie dowodzi, że zależność jest bezpieczna. Wersje trzeba porównać ręcznie z tabelą środowisk powyżej.

Jak sprawdzić ślady

Imperva wskazuje nieoczekiwane zakończenia procesów podczas dekompresji i błędy dekodera jako sygnały, od których warto zacząć ustalanie priorytetów, ale nie jako samodzielny dowód wykorzystania9. Trzeba je zestawić z wersją runtime, logami aplikacji i źródłem skompresowanych danych. Wykonanie kodu w teście Impervy wymagało kilku prób9, więc powtarzające się awarie procesu po odebraniu danych z tego samego źródła są sygnałem wartym uwagi.

Wskaźnik Gdzie zajrzeć
Nieoczekiwane zakończenia procesu w trakcie dekompresji Dziennik procesu, menedżer procesów, nadzór kontenerów
Błędy dekodera Brotli Dziennik aplikacji
Żądania z Content-Encoding: br do usług, które nie powinny przyjmować skompresowanych ciał Dziennik serwera WWW lub proxy
Awarie klienta HTTP po odpowiedziach z Content-Encoding: br od serwerów spoza kontroli Dziennik klienta i ruch wychodzący
Nietypowe procesy potomne i połączenia wychodzące po awarii procesu aplikacji Monitoring procesów, system wykrywania zagrożeń na stacji

Dwa pierwsze wiersze służą do ustalania priorytetu dochodzenia, bo awarie i błędy dekodera nie dowodzą wykorzystania, a klasycznymi wskaźnikami naruszenia bezpieczeństwa są dopiero nietypowe procesy potomne i połączenia wychodzące po awarii, czyli ślady, które zostawia przejęty proces. Zdarzenia z dzienników zbiera system SIEM, a ślady na serwerze i stacji wykrywa EDR, więc to tam najpierw sprawdza się okno, w którym działała podatna wersja. Zdalne wykonanie kodu otwiera atakującemu drogę do instalacji złośliwego oprogramowania, dlatego przy potwierdzonym lub prawdopodobnym włamaniu przed zmianą czegokolwiek zachowuje się dzienniki i obraz dysku.

Podejrzenie włamania to incydent bezpieczeństwa, a jak go zgłosić krok po kroku, pokazuje przewodnik po zgłaszaniu incydentów. CERT Polska, czyli krajowy CSIRT, nie opublikował do 24 października komunikatu o CVE-2026-11149733. Niezależny przegląd aplikacji i jej zależności po usunięciu skutków zlecają firmy z kategorii testy penetracyjne i audyty, a stały nadzór nad zdarzeniami prowadzą firmy z kategorii monitoring i SOC.

Chronologia: od lutowego commita do 24 października

Poprawka trafiła do kodu Brotli 27 lutego o godz. 13:10 UTC, bez opisu bezpieczeństwa4. 21 października Node.js opublikował wydania o 10:38 UTC3, w repozytorium Buna pojawiło się zgłoszenie11, a około 19:27 UTC ukazały się Brotli 1.0.10, 1.1.1 i 1.2.1567. Tego samego dnia Oracle ostrzegł przed CVE-2026-91403 w komponencie JSSE, co jest osobną sprawą: dotyczy certyfikatów urzędu pośredniego eMudhra, które Node.js również uwzględnił w wydaniu z 21 października342.

22 października Bun scalił poprawkę o 02:13 UTC i wydał wersję 1.4.42819, Imperva opublikowała analizę9, ukazało się advisory osobnej luki body-parser16, a o 15:32 UTC pojawił się opis luki w GitHub Advisory Database1. 23 października OpenSourceMalware opisało wpływ luki na Pythona15, Envoy opublikował advisory o 16:03 UTC27, port w Go dostał poprawkę o 17:03 UTC26, a o 19:08 UTC zaktualizowano advisory GitHub, które obejmuje pakiety PyPI1.

24 października wyszły Brotli4j 1.24.014 i gem Ruby 0.9.125, a w dotnet/runtime otwarto pytanie o .NET23.

Oś czasu CVE-2026-111497: 27 lutego poprawka w kodzie Brotli, 21 października wydania Node.js i Brotli, 22 października Bun, Imperva i advisory GitHub, 23 października Python, Envoy i Go, 24 października Brotli4j, gem Ruby i pytanie o .NET
Od poprawki w kodzie do pierwszego wydania z numerem CVE minęło prawie osiem miesięcy, a pozostałe środowiska dołączyły w ciągu trzech kolejnych dni

Ze środowisk z tabeli na 24 października bez poprawki albo bez odpowiedzi pozostają trzy: .NET, w którego zgłoszeniu zespół jeszcze nie odpowiedział23, rozszerzenie PHP z poprawką w otwartym pull requeście24 i pakiet brotli w Debianie forky i sid18.

Źródła

  1. GitHub Advisory Database, "Brotli: Out-of-bounds write in the Brotli decoder (Node2Shell) also affects the PyPI Brotli package" - CVSS 4.0 9,2, zakresy wersji Brotli i Pythona, poprawki, aktualizacja z 23.10.2026 (odczyt 24.10.2026)
  2. Node.js, "Wednesday, October 21, 2026 Security Releases", 21.10.2026 - wydania 22.23.4, 24.22.1 i 26.12.1, mechanizm błędu, ocena "High" (odczyt 24.10.2026)
  3. GitHub, nodejs/node, "2026-10-21, Version 24.22.1 'Krypton' (LTS), @aduh95" - godzina publikacji wydań Node.js, 10:38 UTC (odczyt 24.10.2026)
  4. GitHub, google/brotli, "Detect and report invalid stream earlier.", 27.02.2026 - commit 0ed4268 z poprawką dekodera, bez wzmianki o bezpieczeństwie (odczyt 24.10.2026)
  5. GitHub, google/brotli, "Release v1.2.1" - wydanie 1.2.1 z notą o CVE-2026-111497, publikacja około 19:27 UTC (odczyt 24.10.2026)
  6. GitHub, google/brotli, "Release v1.0.10", 21.10.2026 - wydanie linii 1.0 z poprawką CVE-2026-111497, publikacja około 19:27 UTC (odczyt 24.10.2026)
  7. GitHub, google/brotli, "Release v1.1.1", 21.10.2026 - wydanie linii 1.1 z poprawką CVE-2026-111497, publikacja około 19:27 UTC (odczyt 24.10.2026)
  8. Aikido, "Node2Shell evolves to HTTP2Shell. Brotli flaw (CVE-2026-111497) blast radius affects many libraries & apps using HTTPs.", Dania Durnas, 23.10.2026 - nazwa HTTP2Shell, przebudowa plików Buna, wersje curl i Istio, Apache i nginx, pip-audit i Dependabot, powrót do gzip, odrzucanie odpowiedzi br, brak wykorzystania w Node.js (odczyt 24.10.2026)
  9. Imperva, "Node2Shell: From Brotli Data to Remote Code Execution", Ron Masas, 22.10.2026 - test na Node.js 24.22.0, drogi do błędu, sygnały w logach (odczyt 24.10.2026)
  10. GitHub, miyucy/brotli, "Vendored Brotli 1.2.0 is affected by CVE-2026-111497 (decoder out-of-bounds write)" - sposób dołączania Brotli w gemie i niewiarygodność numeru wersji (odczyt 24.10.2026)
  11. GitHub, oven-sh/bun, "Brotli decoder is missing the CVE-2026-111497 fix (google/brotli@0ed4268a)" - wersje Brotli w Bunie i ścieżki do dekodera (odczyt 24.10.2026)
  12. GitHub, expressjs/body-parser, "body-parser/HISTORY.md at v2.4.0" - obsługa Brotli od 2.0.0, poprawka luki w 2.4.0 (odczyt 24.10.2026)
  13. GitHub, expressjs/body-parser, "body-parser/README.md at v2.4.0" - opcja inflate i jej domyślna wartość (odczyt 24.10.2026)
  14. GitHub, hyperxpro/Brotli4j, "Out-of-bounds write in bundled Brotli decoder (CVE-2026-111497)", 24.10.2026 - narażone wersje, ścieżki, poprawka 1.24.0, brak obejścia (odczyt 24.10.2026)
  15. OpenSourceMalware, "Python Packages Vulnerable to Node2Shell", 23.10.2026 - narażeni klienci HTTP w Pythonie, potwierdzenie z AddressSanitizer, obejścia (odczyt 24.10.2026)
  16. GitHub Advisory Database, "body-parser vulnerable to Denial of Service via trailing bytes after a compressed request body", 22.10.2026 - osobna luka CVE-2026-111181, parsowanie przed routingiem, obejście inflate false (odczyt 24.10.2026)
  17. GitHub, nodejs/node, "node/deps/brotli/c/common/version.h at v24.22.1" - numer wersji Brotli dołączonej do poprawionego Node.js 24.22.1 (odczyt 24.10.2026)
  18. Debian Security Tracker, "CVE-2026-111497" - stan poprawki pakietu brotli w wydaniach Debiana (odczyt 24.10.2026)
  19. Bun, "Bun v1.4.4", 22.10.2026 - wydanie z poprawką Brotli (odczyt 24.10.2026)
  20. GitHub, google/brotli, "Comparing v1.2.0...v1.2.1" - dwa commity i cztery zmienione pliki między wersjami 1.2.0 i 1.2.1 (odczyt 24.10.2026)
  21. GitHub, dotnet/runtime, "runtime/src/native/external/brotli-version.txt at v10.0.13" - wersja Brotli dołączona do .NET: 1.1.0 (odczyt 24.10.2026)
  22. GitHub, dotnet/runtime, "runtime/src/native/external/brotli/c/dec/decode.c at v10.0.13" - kształt funkcji DecodeBlockTypeAndLength sprzed poprawki (odczyt 24.10.2026)
  23. GitHub, dotnet/runtime, "Does CVE-2026-111497 affect System.IO.Compression.Brotli in .NET 9 and 10?", 24.10.2026 - pytanie o CVE w .NET 9.0.21 i 10.0.13, ścieżka przez ASP.NET Core (odczyt 24.10.2026)
  24. GitHub, kjdev/php-ext-brotli, "Update brotli submodule to v1.2.1" - otwarty pull request z poprawką, niescalony na 24.10.2026 (odczyt 24.10.2026)
  25. GitHub, miyucy/brotli, "Use brotli v1.2.1, reject system Brotli without the CVE-2026-111497 fix", 24.10.2026 - poprawka: Brotli 1.2.1 i odrzucanie systemowego Brotli bez poprawki, gem 0.9.1 (odczyt 24.10.2026)
  26. GitHub, andybalholm/brotli, "v1.2.7: Detect and report invalid stream earlier", 23.10.2026 - poprawka portu Go, tag v1.2.7 (odczyt 24.10.2026)
  27. GitHub, envoyproxy/envoy, "Out-of-Bounds Write in Brotli Decompressor", 23.10.2026 - podatne i poprawione wersje Envoya, ocena krytyczna (odczyt 24.10.2026)
  28. GitHub, oven-sh/bun, "Fix regressions since 1.4.3 in bun install, bunx, node:fs and node:http2, and update brotli" - poprawka Buna scalona 22.10 o 02:13 UTC (odczyt 24.10.2026)
  29. GitHub, google/brotli, "prepare for release", 21.10.2026 - commit db24a98 w wydaniu 1.2.1, zmiany w CHANGELOG.md i version.h (odczyt 24.10.2026)
  30. GitHub, miyucy/brotli, "Comparing v0.9.0...v0.9.1" - poprawka CVE-2026-111497 między wersjami 0.9.0 i 0.9.1 gemu (odczyt 24.10.2026)
  31. GitHub, andybalholm/brotli, "Port upstream decoder fix for CVE-2026-111497?" - ten sam wzorzec w porcie Go, przypuszczenie o skutkach (odczyt 24.10.2026)
  32. GitHub, nodejs/Release, "Release/schedule.json at main" - daty końca wsparcia linii 20, 22, 23, 24, 25 i 26 (odczyt 24.10.2026)
  33. CERT Polska, "Komunikaty" - lista komunikatów, stan na 24.10.2026 (odczyt 24.10.2026)
  34. Oracle, "Oracle Security Alert Advisory - CVE-2026-91403", 21.10.2026 - osobny alert dotyczący certyfikatów eMudhra w JSSE (odczyt 24.10.2026)

Kanał RSS

Nowe pozycje z tej sekcji w formacie RSS. Adres kanału do subskrypcji w dowolnym czytniku.

Artykuły z aktualności https://cyberkatalog.pl/feed-artykuly.xml