Przejdź do treści
INDEKS ANALIZ BREACHROAD / NOTA TECHNICZNA

Tie::Hash::Regex CVE-2026-77781: klucz tablicy mógł zakończyć proces Perla

Niepoprawny klucz wejściowy był kompilowany jako regex bez obsługi wyjątku. Analiza FETCH, EXISTS, DELETE, wersji 2.0.0 i bezpiecznego użycia dynamicznych wzorców.

MATERIAŁ PUBLICZNY
AUTOR
/ CEO Breachroad · OSCP · PNPT
PUBLIKACJA
22 sierpnia 2026
CZAS CZYTANIA
16 min czytania
TEMAT
Podatności i CVE
Tie::Hash::Regex CVE-2026-77781: klucz tablicy mógł zakończyć proces Perla

CVE-2026-77781 trafiło 22 sierpnia do publicznych baz podatności. Problem dotyczy modułu CPAN Tie::Hash::Regex w wersjach wcześniejszych niż 2.0.0. Biblioteka pozwala odpytywać tied hash w Perlu nie tylko zwykłym kluczem, ale również wyrażeniem regularnym. Gdy wyszukiwany string nie był istniejącym kluczem, implementacja próbowała skompilować go jako regex bez ochrony przed błędem parsera.

Niepoprawny wzorzec powodował wyjątek w metodach FETCH, EXISTS i DELETE. Jeżeli aplikacja przekazywała do takiego lookupu tekst kontrolowany z zewnątrz i nie miała własnej obsługi wyjątku, pojedyncze żądanie mogło zakończyć bieżący proces lub worker. Rekord klasyfikuje problem jako CWE-248 — nieobsłużony wyjątek. Na moment publikacji nie należy dopisywać mu wyniku CVSS, którego źródło nie podało.

Kiedy biblioteka jest faktycznie osiągalna

Sama obecność paczki w cpanfile, Makefile.PL lub obrazie nie oznacza podatnej ścieżki. Aplikacja musi tworzyć tied hash z Tie::Hash::Regex, wykonywać jedną z objętych operacji i pozwalać, aby niezaufany string dotarł do klucza. Ryzyko rośnie, gdy lookup obsługuje parametr HTTP, pole wyszukiwania, nazwę rekordu z kolejki albo element importowanego pliku.

Znaczenie ma również model procesu. W krótkim skrypcie CLI wyjątek kończy jedno zadanie, które scheduler może powtórzyć. W aplikacji PSGI jeden worker może umrzeć i zostać odtworzony. Powtarzalne wejście może jednak wywołać churn procesów, utratę kolejki, wzrost latency i wyczerpanie limitu restartów. Jeżeli proces wykonuje transakcję, nagłe zakończenie może pozostawić częściowo zrealizowany workflow nawet wtedy, gdy baza wycofa zapis.

Nie ma dowodu na wykonanie kodu, odczyt pamięci ani ominięcie uwierzytelnienia. Mechanizm to dostępność i odporność na błędy parsera. Wpływ biznesowy zależy od tego, czy awaria jest izolowana do jednego requestu, czy zatrzymuje importer, usługę lub proces przetwarzający wiele tenantów.

Jak przeciążona semantyka klucza tworzy ryzyko

Zwykły hash traktuje tekst jako nieprzezroczysty identyfikator. Tie::Hash::Regex dodaje drugą semantykę: ten sam tekst może oznaczać dokładny klucz albo program dopasowujący wiele kluczy. Implementacja najpierw sprawdzała trafienie dokładne, a przy jego braku kompilowała string przez qr//.

To wygodne API, lecz granica typów staje się niewidoczna. Kod wywołujący może uważać, że wykonuje bezpieczne wyszukiwanie nazwy, podczas gdy brak nazwy przełącza bibliotekę w interpreter wzorca. Dwa prawie identyczne inputy podążają różnymi ścieżkami tylko dlatego, że jeden istnieje w zbiorze.

Bezpieczniejszy projekt rozdziela operacje get_exact() i find_by_regex() albo wymaga obiektu regex dla dopasowania wzorcowego. Jeśli kompatybilność wymusza przeciążenie, biblioteka musi traktować błąd kompilacji jako kontrolowany brak dopasowania i dokumentować koszt regexów. Aplikacja nadal powinna zdecydować, czy niezaufanym użytkownikom w ogóle wolno dostarczać wzorce.

Co zmienia wersja 2.0.0

Commit naprawczy zastępuje bezpośrednią kompilację wspólną funkcją _compile. Funkcja wykonuje qr// w bloku eval i zwraca wartość niezdefiniowaną, gdy parser odrzuci wzorzec. FETCH, EXISTS i DELETE sprawdzają wynik przed dalszą pracą. Niepoprawny wzorzec staje się brakiem dopasowania zamiast wyjątku wychodzącego do aplikacji.

Projekt dodał również testy regresji dla wszystkich trzech metod. Sprawdzają one, że operacje nie umierają, zwracają odpowiednik braku wyniku, a nieudane DELETE nie zmienia zawartości hasha. To ważne, ponieważ złapanie wyjątku bez kontroli skutków mogłoby ochronić proces, lecz pozostawić częściową mutację.

Wersja 2.0.0 jest pierwszą poprawioną. Administrator powinien zweryfikować ją w finalnym obrazie i rzeczywistym @INC. Systemowy Perl, lokalny katalog local::lib, vendor bundle i paczka aplikacji mogą zawierać różne kopie modułu, a kolejność ładowania wybiera inną niż wskazuje lockfile.

Aktualizacja bez utraty zachowania

Zaktualizuj zależność, odtwórz lockfile i zbuduj czysty artefakt. Przed rolloutem sprawdź dokładne trafienie, poprawny regex z wynikiem, poprawny regex bez wyniku, niepoprawny wzorzec oraz usuwanie. Aplikacja mogła wcześniej polegać na wyjątku jako sygnale błędnego inputu; po 2.0.0 otrzyma brak dopasowania, więc zachowanie biznesowe trzeba świadomie potwierdzić.

Jeśli klient powinien wiedzieć, że zapytanie było niepoprawne, waliduj regex w warstwie API i zwróć kontrolowany błąd 4xx. Nie przywracaj wyjątku nieobsługiwanego. Rozdziel komunikat użytkownika od logu diagnostycznego, ponieważ logowanie pełnych wzorców może ujawniać dane lub pozwalać na log injection.

Do czasu aktualizacji można opakować lookup w lokalną obsługę wyjątku, ograniczyć dostęp do funkcji wzorcowych i nie przekazywać zewnętrznego inputu jako klucza. To mitygacja w aplikacji, nie naprawa biblioteki. Wspólny moduł może być używany w innym miejscu, którego wrapper nie obejmuje.

Poza wyjątkiem: koszt poprawnych regexów

CVE-2026-77781 opisuje składniowo niepoprawne wzorce. Poprawka nie gwarantuje, że każdy poprawny regex wykona się szybko. Dynamiczne wyrażenia mogą powodować kosztowne backtracking lub przeszukiwać bardzo dużą liczbę kluczy. To odrębne ryzyko dostępności, którego nie należy przypisywać temu CVE, lecz warto uwzględnić podczas przeglądu.

Ustal limity długości inputu i zbioru, timeout lub budżet na operację oraz obserwowalność latency. Jeżeli użytkownik potrzebuje jedynie prefiksu lub wyszukiwania literalnego, nie dawaj mu pełnego języka regex. Escape tekstu lub wyspecjalizowany indeks jest prostszy i przewidywalniejszy.

Detekcja i reagowanie

Szukaj błędów kompilacji regex tuż przed restartem workera, wzrostu 5xx, powtarzających się wejść kończących różne procesy i problemów supervisorów. Logi runtime powinny wskazać moduł i metodę, ale sam stack trace może być niepełny, jeżeli proces kończy się przed flush.

Skoreluj reverse proxy, aplikację, kolejkę i supervisor. Pojedynczy błąd może być literówką legalnego użytkownika; sekwencja podobnych requestów pochodzących z wielu źródeł może nadal reprezentować jeden skaner za proxy. Nie blokuj automatycznie całego adresu NAT bez oceny.

Po potwierdzeniu nadużycia zaktualizuj bibliotekę, odtwórz przerwane zadania idempotentnie i sprawdź, czy wyjątek nie przerwał operacji po częściowym skutku zewnętrznym, na przykład wysłaniu wiadomości. Rotacja sekretów nie wynika z mechanizmu tej podatności.

Projektowanie granicy błędów

Wyjątek z parsera nie powinien sam wybierać granicy awarii. W usłudze webowej kontrolowany błąd jednego parametru powinien zakończyć jeden request, nie cały worker. W konsumencie kolejki wadliwy rekord powinien trafić do dead-letter queue po ograniczonej liczbie prób, zamiast blokować partycję i restartować proces bez końca. Skrypt wsadowy powinien zapisać checkpoint przed przejściem do następnego elementu.

Ustal też kontrakt rezultatu. Brak dokładnego klucza, brak dopasowania, niepoprawna składnia i timeout regexu są różnymi stanami. Wersja 2.0.0 bezpiecznie zamienia błąd kompilacji w brak wyniku na poziomie biblioteki, ale aplikacja może potrzebować rozróżnienia dla użytkownika i metryk. Zrób to w jawnej warstwie walidacji, bez polegania na tekście wyjątku.

Alertuj na tempo błędów i restartów, nie na pojedynczą literówkę. Budżet błędów per tenant chroni współdzieloną usługę, a backoff supervisorów zapobiega pętli start–awaria. Test chaos może bezpiecznie sprawdzić, że zły rekord jest izolowany, o ile odbywa się w środowisku bez danych produkcyjnych i nie generuje niekontrolowanego obciążenia.

Fakty projektu i wnioski Breachroad

Zakres przed 2.0.0, metody FETCH, EXISTS i DELETE, kompilacja niezaufanego klucza oraz sposób poprawki pochodzą z rekordu CVE i commitu projektu. Publiczny rekord nie zgłasza aktywnej eksploatacji ani wyniku CVSS.

Analiza modeli procesu, rozdzielenie API, test rollout i ochrona przed kosztownymi poprawnymi regexami są wnioskami Breachroad. Szkolenia AppSec dla zespołów deweloperskich pomagają rozpoznawać ukryte interpretery w API, a testy penetracyjne aplikacji i API mogą ocenić walidację, obsługę błędów i odporność usługi.

Źródła

UDOSTĘPNIJ / KOPIUJ