Knihovna Transformers 5.17 přestala ukládat cizí kód před souhlasem
Knihovna Transformers uměla převzít z modelového repozitáře vlastní způsob generování. Soubor s cizím kódem však stáhla a uložila do mezipaměti dřív, než se uživatele zeptala, zda mu důvěřuje. Verze 5.17 z 9. září pořadí obrátila; záznam CVE-2026-80047 přitom uvádí zasažené verze jen do 5.8.1, ačkoli stejný sled volání zůstal i v 5.16.1.

Pythonová knihovna Transformers dovoluje nahradit svůj běžný generátor kódem z jiného repozitáře na Hugging Face. Uživatel předá jeho jméno v parametru custom_generate a knihovna si z něj vezme soubor custom_generate/generate.py. Právě pořadí těchto kroků popisuje CVE-2026-80047, zveřejněné 1. září 2026.
Do verze 5.16.1 se soubor nejdřív stáhl a zkopíroval do místní mezipaměti dynamických modulů. Až potom přišlo vyhodnocení trust_remote_code, tedy souhlasu se spuštěním cizího kódu. Když uživatel souhlas odmítl, kód se nespustil. Soubor ale na disku zůstal.
U mezipaměti Transformers už vyšla opačná chyba: na souborovém systému jen pro čtení knihovna vrátila starší soubor, ačkoli na Hubu našla novější. Tentokrát zapisovat mohla, jen se zeptala pozdě.
Dotaz přišel až po zápisu souboru
Chyba není ve funkci, která Python spouští, ale ve sledu tří volání. Metoda load_custom_generate() ve verzi 5.16.1 začínala takto:
module = get_cached_module_file(...)
resolve_trust_remote_code(...)
get_class_in_module("generate", module)
První řádek soubor vyhledal na Hubu, stáhl ho do běžné mezipaměti a pak ho zkopíroval mezi moduly Transformers. Druhý řádek teprve zobrazil dotaz nebo vyhodil chybu, pokud bylo trust_remote_code=False. Třetí řádek modul načetl a spustil. Ochrana tedy správně zastavila poslední krok, nevrátila však ty první dva.
Záznam CVE jmenuje jako cíl adresář ~/.cache/huggingface/modules. Upozorňuje také na možnost, že takto odložený soubor později použije jiný, už důvěryhodný požadavek. Samotné první odmítnutí ale útočný kód nespustilo. Šlo tedy o trvalý zápis bez souhlasu a o riziko pozdějšího použití, ne o okamžité obejití dotazu.
Verze 5.17 obrátila pořadí
Opravu přinesl návrh #48620, otevřený a sloučený 8. září. Mění jediný soubor, přidává 15 řádků a osm odebírá. Nový sled nejdřív přes has_file() ověří, že vzdálený repozitář hledaný soubor vůbec má. Pak vyžádá souhlas a teprve po něm volá funkci, která soubor stáhne:
if not has_file(...):
raise OSError(...)
resolve_trust_remote_code(...)
module = get_cached_module_file(...)
Kontrola existence dál komunikuje s Hubem, ale obsah generate.py na disk neukládá. Poznámky k vydání 5.17.0 změnu uvádějí v oddílu o generování větou o odstranění bezpodmínečného stahování vzdáleného souboru. Číslo CVE u ní nestojí. Hotový balíček se na PyPI objevil 9. září v 15.39 UTC.
Veřejný rozsah verzí končí u 5.8.1
Bezpečnostní tiket NixOS přebírá ze záznamu CVE rozsah od 4.49.0 do 5.8.1. První z těchto balíčků vyšel v únoru 2025, poslední v květnu 2026. Jenže v následující verzi 5.9.0 stojí get_cached_module_file() pořád před resolve_trust_remote_code(). Totéž platí pro 5.16.1 z 26. srpna.
Stejný sled ukazuje přímo porovnání zdrojových souborů. Verze 5.16.1 proti staršímu vydání zpřísnila souhlas i pro kód z místního adresáře, stažení vzdáleného souboru před souhlasem však ponechala. První veřejné vydání, u kterého lze obrácené pořadí doložit, je 5.17.0. Veřejně uvedený konec rozsahu na 5.8.1 proto nepopisuje všechny balíčky se stejnou chybou v toku programu.
Běžného načtení modelu se tahle cesta netýká
Funkce se nepouštěla při každém stažení vah. Sporná větev začínala tehdy, když program přímo zavolal load_custom_generate() nebo předal do generate() vzdálený repozitář v parametru custom_generate. Dokumentace Transformers tu funkci popisuje jako způsob, jak k libovolnému modelu připojit vlastní dekódovací smyčku z Hubu.
Kdo takový parametr nepoužívá, na tuto konkrétní chybu nenaráží. Kdo ho používá se vzdáleným repozitářem, má opravené pořadí od verze 5.17.0. Povýšení balíčku přitom řeší až další stažení. Návrh #48620 dříve uložené dynamické moduly nemaže.