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

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ť sáhne na adresu ve vnitřní síti, a odpověď dostal zpátky celou. Opravu vydal projekt 31. července ve verzi 3.15.0, číslo CVE k ní přibylo o sedmnáct dní později.

Propojovací panely a síťové přepínače v devatenáctipalcovém rozvaděči
Propojovací panely a přepínače v devatenáctipalcovém rozvaděči. Foto: Dsimic, Wikimedia Commons (CC BY-SA 4.0)

K čemu jsou v MLflow webhooky

MLflow je otevřený nástroj, do kterého si týmy zapisují běhy trénování, naměřené hodnoty a hotové modely. Vlastní server se spouští jedním příkazem mlflow server a ve výchozím nastavení jede nad databází SQLite a bez jakéhokoli přihlašování. Přihlášení přidá teprve volitelný modul, který se zapíná přepínačem --app-name basic-auth.

Webhook je odchozí oznámení: jakmile v registru vznikne nová verze modelu nebo se změní její stav, server sám zavolá adresu, kterou mu k tomu někdo předem uložil. Patří k tomu i zkušební rozhraní POST /api/2.0/mlflow/webhooks/{id}/test, které oznámení odešle na povel a volajícímu vrátí stavový kód i celé tělo odpovědi, kterou od té adresy dostalo. To druhé je užitečné, dokud jde uhlídat, kam server chodí.

Pojistka z února kontrolovala adresu, ne spojení

Že se webhookem dá ukázat dovnitř vlastní sítě, projekt věděl. V únoru 2026 přibyla funkce _validate_webhook_url: propustí jen schéma https, přeloží jméno hostitele na adresy a odmítne každou, která není veřejná. Tím padá smyčka, privátní rozsahy i adresa metadatové služby cloudu, kde leží dočasné přístupové údaje stroje. Poprvé to bylo ve verzi 3.10.0 z 20. února.

Kontrola ale výsledek překladu zahodila. Vlastní požadavek se sestavil znovu z té samé adresy a jméno hostitele se překládalo podruhé. Mezi ověřením a spojením tak zůstala mezera, a to hned dvojí. Jméno se dá mezi oběma překlady přepsat, čemuž se říká DNS rebinding. A pak je tu jednodušší cesta: odesílání sledovalo přesměrování, takže stačilo, aby ověřená veřejná adresa odpověděla kódem 302 a poslala server jinam. Cíl přesměrování už nikdo neověřoval.

Na serveru bez přihlašování zvládne obojí kdokoli, kdo se k němu dostane po síti: webhook si založí sám, sám ho zkušebním voláním odpálí a odpověď z vnitřní sítě si přečte v návratu. Hlášení GHSA-7gwp-5pfp-969j vede chybu jako CVE-2026-64849 se známkou 9,3 z deseti, tedy kritickou, a týká se všech verzí před 3.15.0. Oprava, která díru nezavře celou, přitom v oboru není rarita: Keras řešil čtení cizích souborů přes odkazy v souborech HDF5 třikrát za půl roku.

Oprava kontroluje protějšek až po připojení

Opravu poslal Pat Sukprasert v návrhu změny #24258 a projekt ji přijal 2. července. Přibyl s ní soubor mlflow/webhooks/ssrf.py o 144 řádcích. Je v něm adaptér, který se u každého spojení podívá, s jakou adresou se soket opravdu spojil – hned po návratu z connect(), dřív než proběhne šifrované podání ruky. Mezi kontrolou a přenosem už žádný druhý překlad jména není, takže není co přepsat, a protože se ověřuje každé spojení zvlášť, projde tou kontrolou i přesměrování.

Ke stejné změně patří jeden méně nápadný řádek v souboru delivery.py: session.trust_env = False. Kdyby si knihovna vzala nastavení proxy serveru z prostředí, ověřovala by protějšek proxy, ne cíle. Komentář nad ním to říká rovnou.

V poznámkách k vydání je to jeden řádek ze 103

Ven šla oprava 31. července ve verzi 3.15.0 a poznámky k vydání ji jmenují: „Fix DNS-rebinding SSRF bypass in webhook delivery (#24258, @PattaraS)“. Stojí ovšem mezi ostatními změnami v oddílu nazvaném „Other Assorted Features & Improvements“ a nese štítek „[Model Registry]“, ne bezpečnostní. Napočítali jsme v tom oddílu 103 položek a slovo „security“ ani jediné číslo CVE se v celých poznámkách neobjeví. Správce, který si je přečetl, tedy neměl z čeho poznat, že tahle položka spěchá víc než ostatní.

Druhá strana téže věci: od prvního neveřejného hlášení 12. června do přijaté opravy uplynulo dvacet dní a text, který projekt 17. srpna zveřejnil, popisuje chybu podrobně a jmenuje oba nálezce – toho, kdo ji ohlásil neveřejně, i toho, kdo tutéž věc 26. června popsal v otevřeném hlášení #24179. Odstup mezi opravou a jejím pojmenováním má navíc dobrý důvod: dokud aktualizace není venku, popis chyby pomáhá útočníkovi. Stejné pořadí zvolilo v srpnu i Open WebUI, jen s osmidenním odstupem.

Další dvě hlášení téhož dne míří jinam

MLflow zveřejnil 17. srpna ještě dvě hlášení a obě mají opravu v téže verzi 3.15.0. Dopadají ale na jiné nasazení, totiž na to, kde přihlašovací modul zapnutý je. CVE-2026-69148 se známkou 7,1 dovolovalo přihlášenému uživateli založit verzi modelu, která ukazuje do adresáře s výstupy cizího běhu. Ty soubory si pak mohl přečíst, protože kontrola se ptala jen na to, jestli cesta leží uvnitř toho adresáře. Na právo k němu se neptala. CVE-2026-69146 se známkou 6,5 popisuje rozhraní log-inputs, které v seznamu hlídaných volání přihlašovacího modulu úplně chybí. Zápis záznamu do cizího běhu tudy prošel, zatímco zápis naměřené hodnoty do téhož běhu skončil kódem 403.

Název opravy říká míň, než je uvnitř

Pro provoz z toho plyne krátká věta: verze 3.15.0 z 31. července nebo novější, přičemž poslední vydání 3.15.1 je z 3. srpna. A pak je tu jedna věc, kterou název opravy zamlčuje. Návrh změny i řádek v poznámkách mluví o DNS rebindingu, tedy přesně o tom, co popsalo veřejné hlášení. Cesta přes přesměrování, kterou to neveřejné vede jako spolehlivější, v nich nepadne ani slovem, přestože ji nová kontrola zavírá taky. Kdo si podle názvů oprav vybírá, co aktualizovat dřív, přečte si tady míň, než v té změně opravdu je.

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

    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…

  2. Bezpečnost

    Databáze GitHubu zná jen jedno ze čtyř bezpečnostních hlášení brány ContextForge

    Brána ContextForge stojí mezi jazykovým modelem a nástroji, které volá. Její vývojáři zveřejnili 15. června 2026 na repozitáři čtyři bezpečnostní hlášení; do databáze…

  3. Bezpečnost

    Do jména balíčku šlo ve stata-mcp schovat příkaz, který Stata rovnou spustila

    Server stata-mcp pouští statistický program Stata z agentních nástrojů. Do verze 1.19.0 skládal jméno instalovaného balíčku rovnou do příkazu pro Statu, takže se do něj…

  4. Bezpečnost

    Čtení cizích souborů v XAgentu má třetí číslo CVE a opravu jen ve zdrojových kódech

    VulnCheck zveřejnil 11. srpna záznam CVE-2026-72713: obsluha adresy /workspace/file v autonomním agentu XAgent přečte i soubory mimo vyhrazený adresář. Táž funkce už má…