Tak naprawdę, to tytuł tego wpisu ma niewiele wspólnego z jego treścią, ale co mi tam, fajny kawałek :) A o czym chcę napisać? Kilka razy pisałem o tym, że należy stosować walidację danych wejściowych i encoding danych wypisywanych. Teraz chcę zwrócić uwagę na wydawałoby się jedną, oczywistą rzecz. Te środki ochrony należy stosować konsekwentnie.
Poligono Industrial
Jest sobie aplikacja internetowa, w której testach aktualnie uczestniczę. Wykonawca aplikacji ma zwyczaj przyklejania łatek. Polega to na tym, że poprawia błędy tam, gdzie się je wskaże. Jeśli taki sam błąd wystąpi na sąsiednim polu formatki, to poprawiony nie zostanie...
Walidacja...Walidacja danych wejściowych musi być rozwiązaniem systemowym. Oznacza to, że każda dana wchodząca do systemu musi zostać przed użyciem sprawdzona. Najlepiej, gdy taki punkt walidacji jest jeden, spójny dla całej aplikacji. Nie koniecznie trzeba implementować to ręcznie. W ASP.NET są walidatory, jest Struts Validator, jest Commons Validator. Wystarczy trochę pracy na wstępie (definicja reguł walidacji poszczególnych danych), a następnie konsekwentne stosowanie reguł w odniesieniu do tworzonych formularzy.
Encoding...Podobnie w przypadku wypisywania danych. Należy upewnić się, że wszystkie dane wypisywane są w sposób bezpieczny (czyli z kodowaniem encji HTML). Przykładem takiego sposobu może być choćby wykorzystanie za każdym razem funkcji htmlentities w PHP, czy analogiczne w innych językach. Jeśli jakimś cudem takiej funkcji nie ma, należy ją stworzyć. Jak? Banalny przykład jest choćby na stronach OWASP.
A jeśli jest już dziura...Jeśli już zostanie znaleziony jakiś błąd, to należy przeanalizować jak on powstał. Później należy wyszukać podobne fragmenty kodu. Nie trzeba do tego posiadać specjalizowanych narzędzi, w wielu wypadkach wystarczy zwykły grep. No i oczywiście wyrażenia regularne.
A jak to wygląda?W tej aplikacji wygląda to tak, że w funkcji zaawansowanego wyszukiwania, która występuje w kilku miejscach aplikacji, w 50% wystąpień formatki istnieje blind sql-injection. Brak walidacji występuje w większości pól, ale jest encoding (czasami). Dwa pola na tej samej formatce, które określają datę (od - do) potrafią być walidowane w różny sposób. Na trzy sąsiadujące ze sobą pola formatki, w przypadku dwóch jest encoding. W przypadku trzeciego - nie (skutek - XSS). Jak określić taką aplikację? Prosto - pole minowe. Poligon.
No dobrze, ale przecież tylko czasem jest błąd...I co z tego, czy czasem? Jeśli jest sql-injection, to jest ono tak samo groźne jeśli wystąpi tylko raz, jak wówczas gdy wystąpi 10 razy. Różnica jest taka, że w tym pierwszym przypadku trochę trudniej je znaleźć. Dodatkowo częstym błędem jest myślenie, że przez sql-injection uzyska się dostęp do tych danych, które normalnie wyświetla/na których operuje dana funkcjonalność. Aplikacje webowe są zwykle tworzone w ten sposób (niestety), że użytkownik, na którym dana aplikacja działa, ma dostęp do całej bazy danych. Przez sql-injection można więc wyciągnąć dowolne dane, na wstępie trzeba tylko rozpoznać strukturę bazy danych.
Ale firma przetestuje...Tak, przetestuje stan aplikacji na konkretną chwilę. Stan ten jest dynamiczny. Pojawiają się poprawki, pojawiają się nowe funkcjonalności. Pojawiają się nowe, lepsze błędy. Testujący mają skończony (i zwykle dość ograniczony) czas na przeprowadzenie testów. Atakujący tego czasu mają nieskończenie wiele (przynajmniej w zakresie czasu życia aplikacji). Na podstawie wyników testów widać wyraźnie, że:
- nie istnieją systemowe rozwiązania walidacji i encodowania danych,
- nie są przestrzegane najlepsze praktyki w trakcie tworzenia kodu,
- proces tworzenia kodu jest chaotyczny,
- zarządzanie kodem to fikcja,
...i co z tego? (w sensie - i tak ktoś to kupi...)