Databáze GitHubu vedla chybu v MONAI jako opravenou ve verzi, která vyšla před hlášením
Hlášení GHSA-89gg-p5r5-q6r4 o spuštění cizího kódu v knihovně MONAI uvádělo od 7. dubna do 31. července 2026 jako opravenou verzi 1.5.2. Ta přitom vyšla 29. ledna a vadný soubor v ní byl beze změny od července 2024. Skutečnou opravu přinesla až 1.6.0.

MONAI je knihovna pro hluboké učení nad lékařskými snímky. Stojí na PyTorch, vychází pod licencí Apache 2.0 a poslední vydání nese číslo 1.6.0. Databáze bezpečnostních hlášení GitHubu u ní od dubna 2026 vedla záznam o spuštění cizího kódu, a jako opravenou u něj uváděla verzi, ve které ta oprava nebyla.
Co v záznamu stálo
Hlášení GHSA-89gg-p5r5-q6r4 vyšlo 7. dubna 2026, má vysokou závažnost a známku CVSS 7,6. Týká se funkce algo_from_pickle() v souboru monai/auto3dseg/utils.py. Ta přečte soubor a jeho obsah rovnou předá funkci pickle.loads(), aniž by cokoli ověřila. Pickle je pythonovský formát pro uložení objektu do souboru a při rozbalování v něm může být uvedená libovolná funkce, kterou má Python zavolat. Kdo tedy podstrčí připravený soubor .pkl, spustí na cizím stroji svůj kód.
Rozsah zasažených verzí byl v záznamu zapsaný takhle: chyba je ve všem do 1.5.1 včetně, opravená je od 1.5.2.
Proč to číslo nemohlo platit
Verze 1.5.2 vyšla 29. ledna 2026, tedy víc než dva měsíce předtím, než hlášení vzniklo. Samo o sobě to nic nedokazuje, protože oprava klidně může být starší než záznam o ní. Jenže soubor, o který jde, se v té době neměnil vůbec.
Poslední zásah do monai/auto3dseg/utils.py před opravou je z 12. července 2024 a týkal se ukončení podpory Pythonu 3.8. Stáhli jsme si ten soubor ve značkách 1.5.1 a 1.5.2: jsou shodné a volání pickle.loads() v nich stojí na řádcích 321, 350 a 356.
Kdy oprava opravdu přišla
Skutečnou změnu přinesl commit 9078a72f z 18. května 2026 s popisem „Replace pickle with JSON in Auto3DSeg algo serialization“. Do vydání se dostal ve verzi 1.6.0, kterou projekt zveřejnil 11. června 2026; na PyPI je od 22. června.
Databáze si záznam opravila 31. července 2026. Historie souboru v repozitáři github/advisory-database ukazuje dva zápisy. Ten z dubna nese opravenou verzi 1.5.2 a poznámku, že poslední známá zasažená verze je 1.5.1; ten z července už nese 1.6.0 a poznámka v něm chybí. Autora té původní hodnoty z historie nevyčtete, oba zápisy jsou hromadné commity celé databáze.
Jak oprava vypadá zevnitř
Verze 1.6.0 pickle neodstranila. Přibyla k němu dvojice algo_to_json() a algo_from_json(), která se bez něj obejde, a načtení staršího souboru .pkl teď vede přes vnitřní funkci _load_legacy_pickle(). Ta si nejdřív vyžádá svolení: čte proměnnou prostředí MONAI_ALLOW_PICKLE, která je ve výchozím stavu vypnutá. Dokumentační komentář u ní varuje, že pickle umí při načtení spustit libovolný kód a že se má zapínat jen na soubory z důvěryhodných zdrojů. Načítání souborů .pkl je navíc označené za zastaralé.
Po přechodu na 1.6.0 se staré chování dá tou proměnnou zapnout zpátky. Rozdíl je v tom, že se pro to musí rozhodnout.
Špatné číslo je horší než chybějící záznam
Rozsah verzí v těchhle záznamech nečtou hlavně lidé, ale nástroje. Podle něj hlásí Dependabot i skenery závislostí, jestli je nasazená verze v pořádku. Skoro čtyři měsíce jim databáze o knihovně MONAI 1.5.2 odpovídala, že v pořádku je. A nezůstalo to na GitHubu: týž záznam si bere veřejná databáze OSV, ze které čte další řada nástrojů. Ta dnes uvádí tutéž opravenou verzi 1.6.0 a čas úpravy o čtrnáct minut pozdější, než má záznam na GitHubu.
Chybějící záznam se pozná tím, že neukáže nic. Špatné číslo ukáže zelenou. Správce, který si mezi dubnem a koncem července nechal projet závislosti, se o problému nedozvěděl, i když ho měl v produkci.
Ani jedno ze čtyř hlášení, o kterých je tady řeč, nemá číslo CVE. Kdo hlídá jen čísla CVE, nenajde tedy ani jedno z nich. Že obraz v téhle databázi nemusí být úplný, jsme popisovali u brány ContextForge: ze čtyř jejích hlášení znala databáze jediné.
Osmnáctého srpna přibyla další tři hlášení
Záznam GHSA-qxq5-qhx6-94qw z 18. srpna 2026 (vysoká závažnost, CVSS 7,8) popisuje totéž volání pickle.loads() a v titulku vytýká staršímu hlášení, že opravu v 1.5.2 slibovalo neprávem. Rozsah verzí v něm je ale stejný jako v tom starším po červencové opravě: zasažené je všechno pod 1.6.0. V databázi tak dnes leží dva záznamy o téže funkci, které říkají totéž.
Týž den přibyla u MONAI ještě dvě. GHSA-wg9g-w2j2-8pgr (CVSS 7,8) se týká třídy NumpyReader, která volá np.load() s natvrdo zapnutým parametrem allow_pickle=True; podstrčený soubor .npy nebo .npz tím dostane stejnou moc jako podstrčený .pkl. GHSA-rghg-q7wp-9767 popisuje vkládání příkazů operačního systému a jeho text začíná poznámkou japonského týmu JPCERT/CC, že hlášení podává znovu, protože na podání z 5. února a 11. března nedostal odpověď. Obě uvádějí jako opravenou tutéž verzi 1.6.0.
Pro provozovatele z toho plyne jediné číslo. Všechna čtyři hlášení míří na 1.6.0 a starší vydání jsou zasažená bez ohledu na to, co o nich záznam kdy tvrdil. Jak dlouho měla verze 1.5.2 u skenerů zelenou, se dá zjistit jedině z historie toho záznamu. Ze záznamu samotného to nepoznáte.
Zdroje
- GHSA-89gg-p5r5-q6r4 a GHSA-qxq5-qhx6-94qw, databáze bezpečnostních hlášení GitHubu
- Historie záznamu v repozitáři
github/advisory-database - Commit 9078a72f a vydání 1.6.0 v repozitáři projektu MONAI
- Zdrojový soubor
monai/auto3dseg/utils.pyve značkách 1.5.2 a 1.6.0 - Balíček monai na PyPI