Strona główna / Blog / Axolotl: trust_remote_code omijany

Blog · case study

Axolotl: `trust_remote_code` istnieje, ale jedna ścieżka ładowania modelu i tak ustawia `True`

Parametr trust_remote_code w ekosystemie Hugging Face ma czytelny sens: kod z zdalnego repozytorium modelu nie powinien być wykonywany bez świadomej zgody. CVE-2026-86169 pokazuje problem znany VE z innych systemów: security control istnieje, ale nie obowiązuje we wszystkich ścieżkach wykonania. Axolotl do 0.18.0 miał ścieżkę multipack, w której wartość mogła pozostać None, a logika nie traktowała tego jak jawnego False; następnie model był ładowany przez AutoModelForCausalLM.from_pretrained z hardcoded trust_remote_code=True.

CVE-2026-86169 (CVSS v4 8.7): multipack path — None nietraktowany jak False, loader z hardcoded trust_remote_code=True → RCE ze złośliwego repo modelu.
Fix: PR #3858 scalony 24.07.2026 (publiczny rekord CVE dopiero we wrześniu).

Dlaczego None jest problemem bezpieczeństwa

W kodzie aplikacyjnym None często znaczy „użyj domyślnej”. W security-sensitive switchach takie trójstanowe zachowanie jest niebezpieczne, gdy komponenty interpretują je różnie: False = zabroń, True = pozwól, None = brak decyzji. Jeśli jedna warstwa uznaje None za brak zgody, a inna zamienia brak decyzji w True, powstaje fail-open boundary. Nie wystarczy więc sprawdzić, czy produkt „ma flagę bezpieczeństwa” — trzeba znać semantykę wszystkich wartości i propagację flagi przez call graph.

Attack path to często supply-chain/workflow

Atakujący nie musi atakować portu serwera:

operator/pipeline przyjmuje model identifier / HF repo → repo kontrolowane przez atakującego (lub przejęte) → Axolotl uruchamia multipack path → trust_remote_code nie blokuje jak oczekiwano → loader pobiera model i kod → remote code w środowisku treningowym

Asset context ma ogromne znaczenie: proces treningowy może mieć dostęp do GPU nodes, danych, tokenów Hugging Face, object storage, cloud credentials, mounted secrets i artefaktów CI/CD. Dlatego bazowy CVSS nie opowiada pełnej historii blast radius.

SCA daje component finding — VE musi zrobić exploitability finding

Pytania affectedness: czy używamy multipack; czy modele mogą pochodzić z nieufnych repozytoriów; czy trust_remote_code jest jawnie wymuszane na False; czy inne ścieżki loadera nadpisują tę wartość; czy środowisko treningowe ma szerokie uprawnienia. trust_remote_code=False jest compensating control tylko jeśli potwierdzimy, że wszystkie ścieżki loadera respektują tę wartość — najlepiej testem runtime na ścieżce multipack (wskaż testowe repo wymagające remote code i potwierdź, że loader odmawia).

Publiczny fix przed publicznym CVE

PR naprawiający zachowanie scalono w lipcu, a publiczny rekord CVE pojawił się we wrześniu. Patch lineage może istnieć przed pełnym vulnerability intelligence — organizacje śledzące wyłącznie NVD/GHSA dowiedzą się o znaczeniu wcześniejszego commita po czasie. Dla forków/pinned commitów lepszym evidence bywa obecność zmiany z PR #3858 niż sama nazwa wersji (structured advisory nie daje tu pewnej listy patched versions — nie wymyślaj jej z daty merge).

Wniosek

CVE-2026-86169 pokazuje wzorzec: security flag exists → value propagated inconsistently → one loader silently overrides intent → control ineffective. Pojawia się w TLS verification, sandbox toggles, auth modes, feature gates i admission controls. Dlatego pytaj: czy kontrola jest skuteczna na tej ścieżce, którą przejdzie nieufne wejście?

Powiązane na blogu

Źródła

Nota redakcyjna: stan informacji 7 września 2026. CVE-2026-86169 (Axolotl ≤ 0.18.0, CVSS v4 8.7): w ścieżce multipack trust_remote_code mógł pozostać None, a loader ustawiał True → RCE ze złośliwego repo modelu; fix PR #3858 (VII) przed publikacją CVE (IX). Artykuł koncentruje się na skuteczności kontroli na każdej ścieżce i na None jako fail-open.

Zapamiętaj jedno

Pytanie VE nie powinno brzmieć „czy kontrola jest skonfigurowana?”, lecz „czy kontrola jest skuteczna na dokładnie tej ścieżce, którą może przejść nieufne wejście?”. Wzorzec — flaga istnieje, wartość propagowana niespójnie, jeden loader po cichu nadpisuje intencję — powtarza się w TLS verification, sandbox toggles, auth modes i feature gates.