Strona główna / Blog / libheif: security limit i variant analysis

Blog · analiza

libheif: parser ma „security limits”, ale nie każda ścieżka ich przestrzega. Co sześć świeżych advisory mówi o variant analysis?

6 września 2026 maintainerzy libheif opublikowali serię nowych GitHub Security Advisories dotyczących parsera i dekodera HEIF: m.in. nieegzekwowany max_items, nieograniczoną listę iref i rekurencję w sprawdzaniu cykli, deadlock w równoległym dekodowaniu kafelków oraz heap out-of-bounds read w encoder plugins. Każdy z tych błędów można zamknąć jako osobny finding — ciekawsza jest druga warstwa: dlaczego w krótkim czasie pojawia się kilka podatności pokazujących, że granice bezpieczeństwa parsera nie są spójnie egzekwowane? To sygnał do variant analysis, nie tylko do zamykania kolejnych GHSA.

GHSA-vg7w-rp49-4fc2: max_items security limit nie jest egzekwowany dla iinf child boxes.
GHSA-xrp2-63fq-jm8q: unbounded iref entry list + unbounded recursion w kontroli cyklu → crash parsera.
Inne: lock-order inversion (trwały deadlock dekodera), heap OOB read w encoderze przy różnej głębi bitowej luma/chroma, memory leak/uncaught bad_alloc.

Dlaczego max_items jest tak interesujący

Nazwa sugeruje, że projekt ma już mechanizm ochronny ograniczający ilość struktur tworzonych podczas parsowania. A advisory mówi wprost, że limit nie jest egzekwowany dla iinf child boxes. To kluczowa różnica: control exists ≠ control covers every path. Można mieć review, dokumentację lub test pokazujący globalny limit — i to jest niewystarczające, jeśli część struktur powstaje inną ścieżką, omijając wspólną funkcję enforcementu. Analogia: obecność WAF-a czy authorization middleware nie jest dowodem, że wszystkie wejścia przechodzą przez nie przed operacją niebezpieczną.

Nieograniczona lista + rekurencja

GHSA-xrp2-63fq-jm8q łączy unbounded iref entry list z unbounded recursion w kontroli cykli. Parser formatów multimedialnych operuje na grafie relacji, więc potrzeba dwóch invariantów: graf nie może rosnąć poza bezpieczny budżet, a traversal nie może zużywać nieograniczonego stosu ani czasu. Jeśli poprawka adresuje tylko jeden wariant inputu bez centralnego budget accounting, ryzykujemy kolejne sibling bugs.

Czy sześć advisory oznacza, że libheif jest „niebezpieczny”?

Nie. Seria może wynikać z aktywnego fuzzingu, audytu lub skumulowanej publikacji. Sama liczba GHSA nie jest miarą jakości projektu. Ważniejsze pytanie: czy wiele świeżych błędów dotyka tej samej security property? Jeśli tak, remediation plan powinien uwzględnić obserwację kolejnych disclosures w tej rodzinie i ewentualne ograniczenie exposure dla niezaufanych plików.

Attack surface: trzy poziomy affectedness

libheif to biblioteka — instalacja paczki nie mówi jeszcze, czy attacker-controlled HEIF trafia do parsera:

component present → libheif w SBOM/inventory reachable → aplikacja wywołuje dotknięte funkcje parsera/dekodera attacker-controlled → upload, thumbnailing, media service dostarcza niezaufany plik

Dopiero trzecia warstwa pozwala oszacować praktyczną exploitability — szczególnie w usługach przetwarzania mediów, gdzie input przychodzi pośrednio z kolejki lub object storage. Uwaga: brak kompletnego mappingu CVE/package/version nie unieważnia świeżego advisory maintainera.

Które compensating controls coś dają; Fixed vs Mitigated

File-extension filtering jest słabym dowodem (parser identyfikuje format po zawartości). WAF może nie zobaczyć semantyki binarnego HEIF. Za to resource limits/cgroups i process isolation/sandboxing istotnie ograniczają blast radius memory exhaustion czy deadlocku (choć nie usuwają podatności), a odrzucanie HEIF/AVIF przy ingestion bywa deterministyczną mitigacją, jeśli biznes tych formatów nie potrzebuje. Status powinien więc rozróżniać Fixed od Mitigated. Weryfikacja po aktualizacji: nowy obraz, faktycznie pobrany poprawiony artifact, wycofane stare workery, runtime potwierdzający, że stara biblioteka nie jest ładowana (przy statycznym linkowaniu — SBOM/build provenance).

Wniosek

Najważniejsza lekcja to nie „libheif ma sześć nowych advisory”, lecz: mechanizm nazwany „security limit” nie jest security property, dopóki nie wiemy, że obejmuje wszystkie niebezpieczne ścieżki. Punktowy check może zamknąć PoC i jednocześnie zostawić rodzinę podobnych bypassów — dlatego seria sibling bugs powinna uruchamiać variant-analysis mindset.

Powiązane na blogu

Źródła

Nota redakcyjna: stan informacji 6 września 2026. Seria GHSA w libheif dotyczy m.in. nieegzekwowanego max_items, unbounded iref/rekurencji, deadlocku i heap OOB read. Nie wszystkie rekordy miały wtedy jednoznaczne CVE/fixed versions w agregatorach — nie należy ich dopowiadać. Artykuł koncentruje się na variant analysis i różnicy między „control exists” a „control covers every path”.

Zapamiętaj jedno

Mechanizm nazwany „security limit” nie jest security property, dopóki nie wiemy, że obejmuje wszystkie niebezpieczne ścieżki. Seria sibling bugs w krótkim oknie powinna uruchamiać variant-analysis mindset — nawet jeśli każdy advisory ma osobny identyfikator i osobny patch.