Protokol HTTP/2 umožňuje, aby zprávy obsahovaly pojmenovaná pole jak v rámcích obsahujících záhlaví, tak v rámcích ukončující komunikaci. Tato pole jsou v protokolu HTTP/2 serializována jako bloky polí, takže je lze cílové implementaci předat ve více fragmentech.
Mnoho implementací HTTP/2 řádně neomezuje množství zpráv CONTINUATION
odesílaných v rámci jednoho proudu. Útočník, který může odesílat pakety na cílový server, může odeslat proud rámců CONTINUATION
, které nebudou připojeny k seznamu záhlaví v paměti, ale server je přesto přijme a dekóduje, nebo je připojí k seznamu záhlaví, což lze zneužít k zaplnění paměti (OOM).
Hlavička rozdělená do bloků
Hlavní rozdíl mezi HTTP/1.1 a HTTP/2 spočívá v tom, že druhý jmenovaný je binární protokol a klient a server si místo textových řádků vyměňují rámce. Existuje mnoho typů rámců, včetně některých řídicích, které nepřenášejí data, ale umožňují konfiguraci relace HTTP/2 – například SETTINGS
nebo WINDOW_UPDATE
.
Stejně jako protokol HTTP/1.1 používá i protokol HTTP/2 v požadavcích a odpovědích pole hlaviček. Tato pole hlaviček mohou obsahovat seznamy hlaviček, které jsou následně serializovány a rozděleny do bloků. Ty jsou pak rozděleny do blokových fragmentů a přenášeny v rámci rámců HEADER
nebo tzv. rámců CONTINUATION
.
Další dva typy fragmentů bloků záhlaví jsou HEADERS
nebo PUSH_PROMISE
. Rámce CONTINUATION
lze využít k pokračování fragmentu bloku záhlaví, který nebylo možné přenést pomocí rámců HEADERS
nebo PUSH_PROMISE
. Popisuje to RFC 7540, které říká: Rámec
CONTINUATION
(typ=0×9) se používá k pokračování sekvence fragmentů bloku záhlaví.
Standard dále říká, že lze odeslat libovolný počet rámců CONTINUATION
, pokud je předchozí rámec ve stejném datovém toku a je rámcem typu HEADERS
, PUSH_PROMISE
nebo CONTINUATION
bez nastaveného příznaku END_HEADERS
. Standardní komunikace je tedy rozdělena do několika rámců a vypadá nějak takto:
HEADERS
(příznakEND_HEADERS
nenastaven),CONTINUATION
(bez příznaků),CONTINUATION
(bez příznaků),- …
CONTINUATION
(příznakEND_HEADERS
nastaven)
Blok záhlaví je tedy považován za dokončený, když server obdrží nastavený příznak END_HEADERS
. To má znamenat, že již neexistují žádné další rámce CONTINUATION
, HEADERS
nebo PUSH_PROMISE
a přenos bloků byl tedy ukončen. Poté je odeslán buď rámec DATA
s obsahem požadavku, nebo proud HTTP/2 končí.
Některé implementace to nehlídají
Ve několika implementacích HTTP/2 byla objevena chyba, kdy webový server neomezuje množství rámců CONTINUATION
, které lze odeslat v rámci jednoho datového toku. Zatímco ve světě HTTP/1.1 existuje obvykle limit na velikost hlavičky a čas jejího přenosu, v případě některých implementací HTTP/2 takové omezení chybí. Webový server tedy bude neustále poslušně pokračovat v přijímání rámců, dokud nebude během komunikace nastaven příznak END_HEADERS
.
Útočník může inicializovat spojení se serverem pomocí typických rámců HTTP/2 a začít standardní komunikaci otevřením proudu. Útočník pak může zahájit požadavek HTTP bez nastavených příznaků END_HEADERS
, což mu může umožnit odeslat cílovému serveru nekonečný proud rámců CONTINUATION
. Tento typ útoku byl nazván CONTINUATION Flood (záplava).
Výsledek může vést k zaplnění přidělené paměti a následném zápisu mimo hranice. Jádro operačního systému se pak postará o ukončení chybně se chovajícího procesu. To je ovšem útočníkův cíl a umožní mu to provést útok typu DoS (Denial of Service) na cílový server používající zranitelnou implementaci. Ten pak nebude obsluhovat legitimní požadavky.
Útočník může navíc serveru odeslat rámce CONTINUATION
komprimované pomocí algoritmu HPACK určeného pro hlavičky v HTTP/2. To může způsobit vyčerpání prostředků procesoru a opět vést k útoku typu DoS, protože procesor musí dekódovat každý takový přijatý kódovaný rámec.
Nebezpečnější než HTTP/2 Rapid Reset
Podle objevitele chyby, Bartka Nowotarského, představuje tento problém celou třídu zranitelností v několika implementacích protokolu HTTP/2, které představují závažnější hrozbu ve srovnání s útokem HTTP/2 Rapid Reset, jenž se objevil v říjnu 2023.
Ve své zprávě uvádí, že jediný počítač může narušit dostupnost serveru, což může mít různé důsledky, od zhroucení serveru až po výrazné snížení výkonu. V některých případech k tomu stačí i pouhé jedno připojení TCP nebo několik odeslaných rámců. Zajímavé také je, že tato komunikace není přítomná v logovacích souborech serverů.
Absence příznaku END_HEADERS
totiž znamená, že požadavek není řádně uzavřen a server jej celý zatím nezní. Požadavky zákeřného klienta se tak neukládají do logů, což ztěžuje ladění příčin takového útoku. Pro pochopení podstaty této zranitelnosti je tedy nutné analyzovat surové bajty provozu.
Kdo je napadnutelný?
Problém se týká několika různých implementací protokolu HTTP/2 jako: amphp/http (CVE-2024–2653), Apache HTTP Server (CVE-2024–27316), Apache Tomcat (CVE-2024–24549), Apache Traffic Server (CVE-2024–31309), Envoy proxy (CVE-2024–27919 a CVE-2024–30255), Golang (CVE-2023–45288), implementace h2 pro Rust, nghttp2 (CVE-2024–28182), Node.js (CVE-2024–27983) a Tempesta FW (CVE-2024–2758).
Zatím nevíme, jestli je už útok skutečně zneužíván nebo to teprve přijde. Po říjnovém odhalení zranitelnosti nazvané Rapid Reset se velmi rychle objevily rekordní DDoS útoky. CONTINUATION Flood je ale ještě nebezpečnější a je velmi jednoduché ho použít. V některých testovaných implementacích stačilo jedno TCP spojení na shození serveru. Navíc nejde jen o web, ale třeba i o různá důležitá RESTful API.
Uživatelé by měli co nejdříve aktualizovat postižený software na nejnovější verzi, aby se zmírnily potenciální hrozby. Pokud oprava zatím neexistuje, doporučuje se zvážit dočasné zakázání protokolu HTTP/2 na serveru.
(Zdroj: The Hacker News)