Obawy związane z odmową usługi
Najczęstszym problemem związanym z wyrażeniami regularnymi jest atak typu `` odmowa usługi '' za pośrednictwem patologicznych wzorców, które są wykładnicze - lub nawet super-wykładnicze! - i wydaje się, że rozwiązanie zajmuje wieki. Mogą się one pojawiać tylko na określonych danych wejściowych, ale ogólnie można je utworzyć, w przypadku których nie ma to znaczenia.
Które z nich będą zależeć w pewnym stopniu od tego, jak inteligentny jest kompilator wyrażeń regularnych, którego używasz, ponieważ niektóre z nich można wykryć w czasie kompilacji. Kompilatory Regex, które implementują rekursję, zwykle mają wbudowany licznik głębokości rekursji do sprawdzania braku progresji.
Doskonały artykuł Russa Coxa z 2007 r. Na temat dopasowywania wyrażeń regularnych może być prosty i szybki (ale jest powolny w Javie, Perlu, PHP, Pythonie, Ruby, ...) mówi o sposobach, w jakie większość nowoczesnych NFA, które wszystkie wydają się wywodzić z kodu Henry'ego Spencera , ulegają znacznemu pogorszeniu wydajności, ale NFA typu Thompson nie ma takich problemów.
Jeśli przyznajesz tylko wzorce, które można rozwiązać za pomocą DFA, możesz je skompilować jako takie, a będą działać szybciej, prawdopodobnie znacznie szybciej. Jednak zrobienie tego wymaga czasu . Dokument Cox wspomina o tym podejściu i związanych z nim kwestiach. Wszystko sprowadza się do klasycznego kompromisu czasowo-przestrzennego.
W przypadku DFA spędzasz więcej czasu na jego budowaniu (i przydzielaniu większej liczby stanów), podczas gdy w przypadku NFA spędzasz więcej czasu na jego wykonywaniu, ponieważ może to być wiele stanów w tym samym czasie, a cofanie może zjadać twój lunch - i procesor.
Rozwiązania typu Denial-of-Service
Prawdopodobnie najrozsądniejszym sposobem rozwiązania tych wzorców, które są na przegranym końcu wyścigu ze śmiercią wszechświata, jest owinięcie ich zegarem, który skutecznie wyznacza maksymalny dozwolony czas na ich wykonanie. Zwykle będzie to dużo, dużo mniej niż domyślny limit czasu zapewniany przez większość serwerów HTTP.
Istnieją różne sposoby ich implementacji, począwszy od prostego alarm(N)
na poziomie C, poprzez pewnego rodzaju try {}
blokowanie wychwytywania wyjątków typu alarmowego, aż do odrodzenia się nowego wątku, który został specjalnie utworzony z wbudowanym ograniczeniem czasowym.
Objaśnienia kodu
W językach regex, które dopuszczają objaśnienia kodu, powinien być zapewniony mechanizm zezwalania lub blokowania ich w ciągu, który zamierzasz skompilować . Nawet jeśli objaśnienia kodu mają kodować tylko w języku, którego używasz, powinieneś je ograniczyć; nie muszą mieć możliwości wywołania zewnętrznego kodu, chociaż jeśli mogą, masz znacznie większe problemy.
Na przykład w Perlu nie można mieć objaśnień kodu w wyrażeniach regularnych utworzonych z interpolacji ciągów (tak jak byłyby one kompilowane w czasie wykonywania), chyba że use re "eval";
w bieżącym zakresie jest aktywna specjalna pragma o zasięgu leksykalnym .
W ten sposób nikt nie może wkraść się do wywołania kodu, aby uruchomić programy systemowe, takie jak rm -rf *
na przykład. Ponieważ objaśnienia kodu są tak wrażliwe na bezpieczeństwo, Perl domyślnie wyłącza je na wszystkich interpolowanych ciągach i musisz zrobić wszystko, aby je ponownie włączyć.
Zdefiniowane przez użytkownika \ P {roperties}
Pozostaje jeszcze jedna kwestia bezpieczeństwa wrażliwych związane z właściwościami Unicode stylu - jak \pM
, \p{Pd}
, \p{Pattern_Syntax}
, lub \p{Script=Greek}
- że może istnieć w niektórych kompilatorów regex, że wsparcie to notacji.
Problem polega na tym, że w niektórych z nich zestaw możliwych właściwości jest rozszerzalny przez użytkownika. Oznacza to, że możesz mieć właściwości niestandardowe, które są rzeczywistymi wywołaniami kodu do nazwanych funkcji w określonej przestrzeni nazw, takich jak \p{GoodChars}
lub \p{Class::Good_Characters}
. Warto przyjrzeć się temu, jak Twój język obsługuje te elementy.
Piaskownica
W Perlu przedział piaskownicy za pośrednictwem Safe
modułu dawałby kontrolę nad widocznością przestrzeni nazw. Inne języki oferują podobne technologie piaskownicy. Jeśli takie urządzenia są dostępne, warto się do nich przyjrzeć, ponieważ są one specjalnie zaprojektowane do ograniczonego wykonywania niezaufanego kodu.