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

MLflow ve verzích 2.1.0 až 3.14.x ignoroval zákaz pickle u modelů statsmodels

Bezpečnostní volba v MLflow měla zastavit načítání modelů uložených pomocí pickle, integrace statsmodels ji ale nekontrolovala. Upravený modelový artefakt proto mohl při načtení spustit kód i s nastavením MLFLOW_ALLOW_PICKLE_DESERIALIZATION=False. Verze 3.15.0 kontrolu doplnila a projekt podrobnosti zveřejnil 1. září.

Titulní snímek prezentace Por que Python z roku 2008
Titulní snímek prezentace „Por que Python?“ z roku 2008. Foto: Érre, Wikimedia Commons (CC BY-SA 2.0)

Integrace statsmodels přeskočila společnou pojistku

MLflow ukládá modely v několika takzvaných flavors, tedy integracích pro konkrétní knihovny a formáty. Stejný model pak lze načíst přímo přes jeho integraci nebo společnou funkcí mlflow.pyfunc.load_model(). U modelů z knihovny statsmodels vedou obě cesty nakonec do funkce statsmodels.iolib.load_pickle().

Formát pickle není obyčejný balík dat. Při obnově objektu může zavolat funkci a tím spustit kód. Dokumentace Pythonu proto říká, že se mají načítat jen důvěryhodná data. Statsmodels u své funkce varuje stejně: model z nedůvěryhodného nebo neověřeného zdroje se nemá rozbalovat.

MLflow má pro takové nasazení proměnnou MLFLOW_ALLOW_PICKLE_DESERIALIZATION. Hodnota False má načítání pickle zastavit. Integrace pro scikit-learn, PyTorch nebo pmdarima ji kontrolovaly, statsmodels ne. Ve verzi 3.14.0 funkce _load_model() rovnou zavolá smio.load_pickle(path). Hodnota bezpečnostní volby se v souboru vůbec nečte.

Kód se spustil až při načtení artefaktu

Podmínka útoku je důležitá. Nestačí otevřít webové rozhraní nebo si prohlédnout kartu modelu. Útočník musí dostat upravený soubor MLmodel a škodlivý pickle do úložiště, ke kterému má oběť přístup. Potom musí nějaký proces zavolat mlflow.pyfunc.load_model() nebo mlflow.statsmodels.load_model() nad tímto artefaktem.

Bezpečnostní hlášení GHSA-gqvg-gmmx-x4hm upozorňuje, že výchozí server MLflow nemá zapnuté přihlašování. Z toho ale neplyne, že každý server na internetu dovolí komukoli podstrčit a načíst model: rozhodují práva k úložišti, způsob nasazení a to, kdo operaci načtení spustí. Hlášení hodnotí chybu známkou 8,8 z deseti a uvádí nutnou součinnost uživatele. Číslo CVE zatím přidělené nemá.

Rozsah ve stejném záznamu začíná verzí 2.1.0 a končí těsně před 3.15.0. Jako první opravenou verzi uvádí jen 3.15.0, nikoli některé vydání řady 2.x. Správci starší hlavní řady tak nemají v hlášení uvedenou opravenou větev, na které by mohli zůstat.

Verze 3.15.0 hlídá oba způsoby načtení

Opravu přinesl návrh změny #24686, přijatý 27. července. Kontrola teď stojí přímo na začátku _load_model(), tedy před voláním statsmodels. Při zakázané deserializaci vyhodí MLflow výjimku a k pickle se nedostane. Test zkouší obě veřejné cesty načtení, přímou funkci statsmodels i společné pyfunc.load_model().

Kód zachovává stejnou výjimku jako ostatní integrace MLflow: kontrolu nepoužije uvnitř Databricks Runtime a v prostředí Databricks Model Serving. Nejde o přehlédnutou větev nové opravy, ale o záměr, který opravný commit přebírá ze sourozeneckých integrací.

MLflow 3.15.0 vyšlo 31. července. Poznámky k vydání opravu uvádějí jedním řádkem mezi běžnými opravami modelů, bez známky závažnosti a bez odkazu na neveřejné hlášení. Veřejný popis chyby přibyl 1. září, tedy o 32 dní později. Oprava tak byla měsíc dostupná, ale její dopad se z poznámek k vydání určit nedal.

Původ modelu zůstává po aktualizaci rozhodující

Aktuální vydání 3.15.2 z 26. srpna už opravu obsahuje. Aktualizace zavře konkrétní mezeru v integraci statsmodels, ale z pickle neudělá bezpečný formát. Modelové artefakty dál patří do stejné kategorie jako spustitelný kód: úložiště potřebuje řízení zápisu a původ modelu se musí ověřit před načtením.

Přepínač s hodnotou False má smysl jako druhá pojistka. Tahle chyba ukazuje jeho mez: globálně pojmenovaná bezpečnostní volba chránila jen integrace, které ji skutečně zkontrolovaly. Vlastní nebo méně obvyklé loadery je proto potřeba prověřovat podle kódu, ne podle názvu proměnné.

Zdroje

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

    Přihlášený uživatel OpenShift AI může načíst společné klíče NVIDIA

    Red Hat zveřejnil 7. září zranitelnost CVE-2026-86332 se skóre 6,5. Přihlášený uživatel dashboardu OpenShift AI může bez správcovského oprávnění načíst společný klíč…

  2. Bezpečnost

    Hlídač agentů v API OpenAI umí konverzaci zastavit, hotové kroky ale nevrátí zpět

    Spolu s modelem GPT-6 Astra ohlásilo OpenAI 3. září 2026 systém, který na pozadí čte uvažování agenta a při podezření na nezamýšlený přenos dat nebo destruktivní zásah…

  3. Bezpečnost

    Dynamicky sestavený Bifrost mohl bez přihlášení spustit modul z webu

    Správní rozhraní AI brány Bifrost před verzí 2.0.0 přijímalo od nepřihlášeného volajícího internetovou adresu vlastního zásuvného modulu. V dynamickém sestavení mohl…

  4. Bezpečnost

    Souběžné načtení dvou vektorů promptu obešlo ve vLLM pojistku proti loňské díře

    Záznam CVE-2026-73557 popisuje, že pojistka, kterou vLLM přidal v prosinci 2025 proti chybě CVE-2025-62164, stála na přepínači společném pro celý proces. Když server…