Strona główna / Blog / Hugging Face: consent po file-write

Blog · case study

Klikasz „nie ufam”, ale złośliwy Python już leży w cache: Hugging Face Transformers pokazuje, że consent check wykonany po file-write nie jest security control

trust_remote_code ma prostą obietnicę: jeśli model wymaga custom Python code, biblioteka pyta „czy ufasz temu zdalnemu kodowi?”, a odpowiedź „nie” powinna znaczyć „nic trwałego się nie stało”. CVE-2026-80047 pokazuje, że w jednej ścieżce Transformers było inaczej. W GenerativePreTrainedModel.load_custom_generate() kod z repozytorium był pobierany i kopiowany do lokalnego cache zanim wywołano resolve_trust_remote_code(). Consent następował po nieodwracalnym side effect.

CVE-2026-80047: load_custom_generate() zapisuje custom_generate/generate.py do ~/.cache/huggingface/modules przed sprawdzeniem trust.
Affected: Transformers 4.49.0–5.8.1 (CERT/CC).
Stan vendora (01.09): brak vendor-provided patch/advisory; status niepotwierdzony.

Co jest potwierdzone, a czego nie dopisywać

Potwierdzone: remote attacker-controlled Python file → fetched → persisted locally → before consent. Nie należy pisać „odmowa promptu natychmiast wykonuje RCE” — CERT/CC podkreśla, że execution jest nadal gated. Problem to unauthorized persistent code write, który może mieć późniejszy impact w środowisku z reused cache.

„Nie wykonałem kodu” nie oznacza „system jest czysty”

Developer ładuje złośliwy model, odmawia trust — na ekranie bezpiecznie. Ale lokalnie zostaje ~/.cache/huggingface/modules/.../generate.py. Jeżeli później inny workflow ufa temu modelowi, cache zostanie ponownie użyty albo inny pipeline przyjmie inny trust decision — stary attacker-controlled file może wejść do kolejnej ścieżki. CERT/CC wskazuje reused cache jako potencjalny mechanizm późniejszego unintended execution.

Meta-wzorzec: decyzja po side effect

To nie klasyczny race condition, lecz side effect at T1, consent decision at T2, T1 < T2. Security decision działa, ale za późno, by zapobiec pierwszej części skutku. Ten sam meta-wzorzec co authorization przed tenant resolution, validation przed canonical path resolution czy sandbox przed second render. Ważny wniosek dla AI/ML: cache staje się security state — remediation nie kończy się na upgrade Transformers, jeśli plik został już zapisany.

Patch vs cleanup; dlaczego trust_remote_code=False nie wystarcza

Dwie różne rzeczy: (1) fix future behavior — gdy vendor da poprawkę consent before fetch/write; (2) remove historical artifacts — inspect/clear ~/.cache/huggingface/modules. Patch nie cofa przeszłych side effects (jak credential rotation po wycieku czy CI cache invalidation). A jeśli aplikacja zakłada „trust_remote_code=False → no remote code reaches disk", CVE obala właśnie to założenie: execution blocked ≠ remote code ingestion blocked — to różnica między execution control a content acquisition control.

Statusy i finding

Nie RCE (brak execution evidence) i nie harmless (bo odmówiono). Lepsze: UNAUTHORIZED_CODE_PERSISTENCE + EXECUTION_NOT_CONFIRMED. Bieżąca mitygacja (CERT/CC): unikać load_custom_generate() dla untrusted repos, inspekcja/cleanup cache, trust check przed fetch/write; dodatkowo ephemeral cache per build, isolated execution, allowlist repos, monitoring nowych plików w HF module cache. Nie wolno wymyślać fixed version.

Wniosek

CVE-2026-80047 to świetny przykład dla AI security i VE: security decision musi poprzedzać pierwszy nieodwracalny side effect. Inaczej UI mówi „odmówiono”, podczas gdy system już zmienił persistent state — a cache jest częścią assetu i remediation.

Powiązane na blogu

Źródła

Nota redakcyjna: stan informacji 2 września 2026. CERT/CC wskazuje affected Transformers 4.49.0–5.8.1 oraz brak vendor-provided patch/advisory w momencie publikacji 01.09. Artykuł świadomie rozróżnia persistent unauthorized file write od potwierdzonego immediate RCE po odmowie consent.

Zapamiętaj jedno

Consent jest security control tylko wtedy, gdy wszystkie security-relevant side effects następują po nim. Jeśli plik trafia na dysk wcześniej, użytkownik może powiedzieć jedynie „nie wykonuj teraz”, nie „nie” dla całej operacji — a cache staje się częścią assetu i remediation.