Přeskočit na obsah
Bezpečnost 4 min čtení

Knihovna Transformers čte podle indexu i soubory mimo složku modelu a opravu nemá

Když Transformers načítá model rozdělený do víc souborů, vezme jejich jména z indexu ležícího vedle vah a připojí je ke složce modelu bez jediné kontroly. Jméno, které ze složky vede pryč, tak projde a knihovna otevře soubor někde jinde na disku. Nálezce chybu poslal do programu odměn v červnu, hlášení v repozitáři po měsíci ticha zavřel automat a záznam CVE-2026-75104 vyšel 17. srpna bez opravené verze.

Kartotéční skříň v katalogové místnosti finského Národního archivu
Kartotéční skříň v katalogové místnosti finského Národního archivu v Helsinkách. Index u vah modelu plní stejnou roli: říká, ve kterém souboru se má hledat. Foto: Fuje23, Wikimedia Commons (CC BY-SA 4.0)

Index říká, ve kterém souboru která váha leží

Váhy velkého modelu se do jednoho souboru nevejdou, a tak se ukládají po kusech. Vedle nich leží index – soubor model.safetensors.index.json nebo jeho starší obdoba pro formát .bin –, který u každého tenzoru uvádí, ve kterém kusu se má hledat. Knihovna Transformers od Hugging Face si při volání from_pretrained ten index přečte a otevře soubory, které v něm stojí. Jde o nejběžnější způsob, jak se dnes model načítá; za poslední měsíc si balíček z PyPI vzalo podle pypistats.org 195 692 642 stažení.

Jméno z indexu se připojí ke složce bez kontroly

Funkce get_checkpoint_shard_files v souboru src/transformers/utils/hub.py vezme hodnoty z indexu a u modelu, který leží v místní složce, je k ní prostě přilepí:

shard_filenames = sorted(set(index["weight_map"].values()))
...
if os.path.isdir(pretrained_model_name_or_path):
    shard_filenames = [os.path.join(pretrained_model_name_or_path, subfolder, f) for f in shard_filenames]

Funkce os.path.join ale cestu nenarovnává. Když jméno v indexu obsahuje odkaz na nadřazený adresář, výsledek ze složky modelu vede pryč; když je jméno rovnou absolutní cesta, předchozí část se zahodí celá. Nikde v té funkci není normpath, commonpath ani nic, co by absolutní cestu odmítlo. Knihovna pak otevře, co v indexu stojí, a u souboru ve formátu safetensors načte i jeho obsah.

Druhá větev té funkce, tedy model stahovaný z Hugging Face podle jména, jde jinudy – jména se předávají stahovací funkci cached_files, ne spojení cest. Nálezce k tomu píše, že tudy se chyba využít nedá, protože se jména porovnávají se seznamem souborů na serveru. Doložený případ je tak složka s modelem, kterou někdo dostal jinak: rozbalený archiv, sdílený adresář na stroji s víc uživateli, naklonovaný repozitář.

Známka je střední, protože oběť musí model sama načíst

Popis v záznamu CVE-2026-75104 mluví o čtení souborů mimo složku modelu a o ohledávání souborového systému, ne o spuštění cizího kódu. Tomu odpovídají i známky: 6,8 podle CVSS 4.0 od firmy VulnCheck, která číslo přidělila, a 5,5 podle starší CVSS 3.1 v databázi GitHubu. Obě řadí útok mezi místní a obě počítají s tím, že oběť musí sama něco udělat – načíst model, který dostala od někoho cizího.

Hlášení zavřel časovač

Nálezce vystupující jako geo-chen píše, že chybu poslal 8. června do programu odměn, na který odkazuje bezpečnostní politika projektu, a odpovědi se nedočkal. Když se měsíc nic nedělo, otevřel 8. července v repozitáři dvě veřejná hlášení: číslo 47176 o čtení mimo složku a číslo 47177 o zápisu mimo složku při rozbalování archivu.

Odpověď přišla jen k tomu druhému. Vývojář projektu 9. července napsal, že převodní skripty se do vydávaných balíčků nedostávají, protože musí otevírat i nebezpečné formáty, a jsou určené pokročilým. Nálezce mu den nato odpověděl, že první hlášení se převodních skriptů netýká: jde o běžnou pomocnou funkci, která je v každém vydání a kterou zavolá obyčejné načtení modelu. Na to už nikdo nereagoval. Osmého srpna označil obě hlášení automat za odložená kvůli nečinnosti a 17. srpna je tentýž automat zavřel. Ještě týž den vyšel v databázi NVD záznam CVE.

Záznam, na který hlídač závislostí nereaguje

Ten záznam má v databázi GitHubu tři vlastnosti, které stojí za přečtení. Je označený jako nekontrolovaný (unreviewed), tedy převzatý automaticky z NVD. Nemá vyplněný ani jeden dotčený balíček. A podle vlastní dokumentace GitHubu platí, že „Dependabot pro nekontrolovaná hlášení upozornění nevytváří, protože se u tohohle druhu neověřuje platnost ani úplnost“ (přeloženo). Kdo se spoléhá na automatické hlášky o zranitelných závislostech, ten se o téhle chybě nedozví.

Rozsah dotčených verzí uvádí jen hlášení VulnCheck, a to slovy „transformers <= 5.15.0“. Vydání 5.15.1 je z 19. srpna, tedy dva dny po záznamu, takže do toho rozsahu nespadá. Stáhli jsme si soubor hub.py přímo z té značky vydání a popsaná funkce je v něm slovo od slova stejná jako předtím; totéž platí pro hlavní větev ke 20. srpnu. Od 8. července se toho souboru dotkl jediný commit, a byla to oprava vydávání starého souboru z cache na systémech jen pro čtení. Číslo verze, ve které je chyba spravená, tedy zatím žádné není.

Co s tím může udělat, kdo modely načítá

Dokud oprava nevyjde, zůstává jediné vodítko v tom, odkud složka s modelem přišla. Model stažený z Hugging Face podle jména jde druhou větví. U adresáře, který se objevil jinudy, se dá index otevřít obyčejným textovým editorem a podívat se, jestli jsou v weight_map jen holá jména souborů – ne cesty s lomítky, ne odkazy nahoru, ne absolutní cesty. Je to kontrola na pár vteřin a dá se automatizovat, ale vychází ze čtení kódu, ne z pokusu – sami jsme ji na podvrženém indexu nezkoušeli.

Zbytek je na projektu. Hlášení je veřejné od července, popis chyby včetně místa v kódu je v něm celý a oprava vypadá na pár řádků. Zavřel ho ale časovač, ne člověk, takže z pohledu repozitáře je věc vyřízená.

Zdroje: záznam CVE-2026-75104 v NVD, GHSA-fv5v-hfxp-5379, hlášení VulnCheck, hlášení 4717647177 v repozitáři Transformers, zdrojový kód hub.py, historie vydání na PyPI.

Diskuse

Zatím tu nikdo nediskutuje. Můžete být první.

Napsat příspěvek

Diskutovat můžete i bez účtu. S registrací se ale příspěvek zveřejní hned a nemusíte pokaždé vyplňovat jméno. Účet už máte? Přihlaste se.

Nezveřejňujeme ho, slouží jen redakci.

Podporuje zápis Texy: **tučně**, *kurzíva*, odrážky, odkazy.

Dál k tématu

  1. Bezpečnost

    Servery MCP rodiny faf mají opravu, tři jejich kopie na npm ji nemají

    Databáze GitHubu vydala 19. srpna 2026 tři bezpečnostní hlášení k balíčkům faf-mcp, claude-faf-mcp a grok-faf-mcp: jejich nástroje si nechaly podstrčit cestu k…

  2. Bezpečnost

    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…

  3. Bezpečnost

    Webhooky MLflow vydaly obsah z vnitřní sítě i nepřihlášenému útočníkovi

    Výchozí server MLflow nechává rozhraní pro webhooky bez přihlášení a jeho pojistku proti SSRF šlo obejít obyčejným přesměrováním. Útočník tak mohl serveru poručit, ať…

  4. Bezpečnost

    OpenClaw pustí uložený klíč jen na vyjmenované servery, zatím v předběžném vydání

    Agentní nástroj OpenClaw vydal 15. srpna předběžnou verzi, ve které podřízený proces místo klíče k cizímu rozhraní dostane jen zástupnou hodnotu. Skutečný klíč za ni…