
V dekodéru Brotli od Google existuje chyba v korupci paměti, která je hodnocena jako kritická s hodnotou 9.2 podle CVSS v4.0 a postihuje všechny verze od 1.0.3 do 1.2.0. Node.js ji 22. října oznámil jako Node2Shell. Python následující den vydal advisory pro stejnou chybu, protože balíčky Brotli a brotlicffi na PyPI kompilují stejný dekodér. Pokud váš stack komunikuje přes HTTP a dekompresuje odpovědi, pravděpodobně se tato chyba právě teď nachází ve vašem stromu závislostí.
Funguje to oběma směry
Vzdálený neautentizovaný útočník odešle upravený Brotli-komprimovaný proud a dekodér nadále přijímá bajty, které by měl odmítnout. Tyto bajty přetečou malou pracovní paměť. Za tímto bodem může útočník vytéct paměť, zkrachovat proces nebo převzít kontrolu nad tím, co se spouští. Nepříjemnou částí je, že to funguje oběma směry: zlovolný klient může převzít neopravený server, který přijímá komprimovaná těla požadavků, a zlovolný server může převzít neopravený klient, který přijímá komprimované odpovědi.
OpenAI ji objevila v únoru a nahlásila ji jako vzdálené spuštění kódu bez autentizace. Tento datum je důležité a důvod, proč je důležité, není nikomu lichotivý.
Příčinou je boolean
Chyba se nachází v funkci DecodeBlockTypeAndLength, která zpracovává přepínání bloků, tedy body, kde Brotli proud změní, kterou Huffmanovu strom používá. Zranitelné verze vrací obyčejný boolean a hodnota false může znamenat dvě velmi odlišné věci. Buď je proud nesprávně formátovaný, nebo dekodér potřebuje více vstupu. Volající funkce nedokážou rozlišit, které z toho platí. Na rychlé cestě dekodér hodnotu návratu zcela zahodí.
Upřavený proud může deklarovat jediný typ bloku a poté vyčerpat délku tohoto bloku. To vynutí přepnutí, které nemůže uspět. Dekodér pak buď nahlásí, že potřebuje více vstupu pro proud, který je již dokončen, nebo pokračuje v dekódování se stavem bloku, který měl dříve. Druhá cesta je zápis mimo meze paměti.
Horní oprava, commit 0ed4268 v google/brotli, způsobí, že funkce vrací chybový kód a přidá nový, BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH, což je minus sedmnáct. Dekódování se nyní zastaví při formátové chybě na obou cestách, bezpečné i rychlé. Porovnání zdrojových balíčků 1.2.0 a 1.2.1 ukazuje, že jediná významná změna je tento commit a zvýšení verze.
Oprava tedy existuje ve zdrojovém kódu od února. Co neexistovalo, byla release. Brotli 1.2.1 je první vydaná verze, která ji obsahuje, což znamená, že každý projekt, který Brotli balí, musel čekat a každý projekt, který Brotli balí, musí nyní vydat vlastní aktualizaci.
Váš skener je na tuto chybu slepý
Nemusíte Brotli importovat, aby vás tato chyba postihla. HTTP klienti jako requests, httpx a aiohttp načtou balíček automaticky, pokud je přítomen. Zpráva od Aikido je ohledně praktických důsledků přímá: k 23. říjnu databáze advisory tuto CVE nemapují na žádný z balíčků na PyPI, takže pip-audit, Dependabot a Safety neoznačí zranitelné verze. Můžete spustit čisté skenování a stále běžíte na 1.2.0.
Další dva detaily stojí za to si zapamatovat. Apache mod_brotli Brotli nedekóduje, takže tato cesta není postižena. A přepnutí hlavičky Accept-Encoding není opravou, protože zlovolný server může odeslat Brotli odpověď bez ohledu na to, co klient deklaruje, a urllib3 si vybírá dekodér z hlavičky Content-Encoding odpovědi, ne z toho, co jste řekli, že chcete.
Co skutečně udělat
Aktualizujte na Brotli 1.2.1 nebo brotlicffi 1.2.1.0 ve všech prostředích, kde se nachází. Poté přestavte kontejnerové obrazy, které ho balí, protože lock file na hostiteli nic neudělá pro vrstvu, která už sedí ve vašem registru. Znovu nasadte, restartujte služby a potvrďte, že běžící workloads běží na opravené buildu, místo abyste předpokládali, že pipeline udělala to, co jste jí řekli.
Část, ke které se neustále vracím, je mezera mezi opravou a release, ne samotná chyba. Chyba v korupci paměti v jedné z nejstahovanějších kompresních knihoven na internetu byla v únoru správně diagnostikována, opravena ve zdrojovém kódu a přesto se dostala do světa jako kritická advisory v říjnu, protože ji nikdo nebral jako bezpečnostní release. Tato mezera se bude opakovat. Je to také důvod, proč vám nikdo nemůže poskytnout zprávu ze skeneru, která říká, že je vše v pořádku.