Chcę dodać możliwość wyszukiwania wyrażeń regularnych do mojej publicznej strony internetowej. Czy oprócz kodowania danych wyjściowych w formacie HTML muszę robić cokolwiek, aby zabezpieczyć się przed wprowadzaniem danych przez złośliwego użytkownika?
Wyszukiwania Google są zalewane przez ludzi rozwiązujących odwrotny problem - używając wyrażeń regularnych do wykrywania złośliwych danych wejściowych - co mnie nie interesuje. W moim scenariuszu dane wejściowe użytkownika są wyrażeniami regularnymi.
Będę używać biblioteki Regex w .NET (C #).
Odpowiedzi:
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 rodzajutry {}
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.źródło
Dodając do doskonałej odpowiedzi tchrista: ten sam Russ Cox, który napisał stronę „Wyrażenia regularne”, również opublikował kod! re2 to biblioteka C ++, która gwarantuje O (length_of_regex) czas wykonywania i konfigurowalny limit wykorzystania pamięci. Jest używany w Google, dzięki czemu możesz wpisać wyrażenie regularne w wyszukiwarce kodu Google - co oznacza, że zostało przetestowane w walce.
źródło
Tak.
Regexes mogą być używane do wykonywania ataków DOS .
Nie ma prostego rozwiązania.
źródło
Będziesz chciał przeczytać ten artykuł:
Niezabezpieczone przełączanie kontekstu: inokulowanie wyrażeń regularnych w celu zapewnienia przetrwania Artykuł jest bardziej o tym, co może się nie udać w silnikach wyrażeń regularnych (np. PCRE), ale może pomóc ci zrozumieć, z czym masz do czynienia.
źródło
Musisz martwić się nie tylko o samo dopasowanie, ale także o to, jak to zrobić. Na przykład, jeśli dane wejściowe przechodzą przez jakąś fazę ewaluacji lub podstawianie poleceń w drodze do silnika wyrażeń regularnych, może istnieć kod, który jest wykonywany wewnątrz wzorca. Lub, jeśli twoja składnia wyrażeń regularnych pozwala na osadzone polecenia, również musisz być tego ostrożny. Ponieważ nie podałeś języka w swoim pytaniu, trudno powiedzieć z całą pewnością, jakie są wszystkie konsekwencje dla bezpieczeństwa.
źródło
Dobrym sposobem na przetestowanie RegEx pod kątem problemów z bezpieczeństwem (przynajmniej dla Windows) jest narzędzie do fuzzingu SDL RegEx wydane niedawno przez Microsoft. Może to pomóc uniknąć patologicznie złej konstrukcji wyrażeń RegEx.
źródło