Bezpieczeństwo aplikacji PHP

- Dane, którym nie możesz ufać: parametry URL, dane pochodzące z formularzy, ciasteczka, nagłówki HTTP, pliki przesyłane przez użytkowników (tablice $_GET, $_POST, $_COOKIE, $_REQUEST, $_SERVER, $_FILES oraz ich odpowiedniki).
- Błędy poziomu “notice” to też błędy - wykorzystaj error_reporting(E_ALL).
- Jeżeli Twój serwis przetwarza dane o niejednolitym kodowaniu, zamień je na kodowanie wewnętrzne przed walidacją/filtrowaniem, oraz na kodowanie wyjściowe przed przesłaniem do przeglądarki (mb_convert_encoding() lub iconv()). Jeśli stosujesz wielobajtowe kodowanie, upewnij się, że wewnątrz danych nie ma znaków nieprawidłowych w tym kodowaniu. Nie zapomnij o zdefiniowaniu kodowania w wyjściowym dokumencie HTML (header(’Content-Type: text/html; charset=utf-8′); oraz <meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />).
- Możesz zastanowić się nad metodą oznaczania zmiennych - które z nich pochodzą od użytkownika, które przeszły filtrowanie HTML, a które są w postaci przeznaczonej do zapisu w bazie danych? Takie oznaczanie za pomocą nazw zmiennych nie zawsze jest uzasadnione (i nie zawsze możliwe do wykonania), ale warto o tym pomyśleć.
- Przygotuj osobne metody filtrowania przeznaczone dla typów danych oraz miejsc, w których znajdą się w wynikowym dokumencie HTML. Prawdopodobnie będziesz potrzebował filtrów dla: zwykłego tekstu (htmlspecialchars() + ENT_QUOTES), kodu HTML generowanego przez użytkownika (być może przyda Ci się HTML Purifier), fragmentów atrybutów HTML (htmlspecialchars() + ENT_QUOTES, czasami urlencode()) oraz wartości wstawianych wewnątrz skryptów JavaScript (tutaj poza <>"'& należy uważać na ;.%\{}()+ oraz \r i \n).
- Jeśli z jakiegoś powodu nie możesz zastosować do kodu HTML tworzonego przez użytkowników filtra typu “whitelist” (np. HTML Purifier), czeka Cię naprawdę ciężki orzech do zgryzienia. Zweryfikuj swój filtr za pomocą XSS Cheat Sheet. Strona ta nie zawiera wszystkich możliwych metod obejścia filtrów XSS, ale daje ogólne pojęcie o tym, co Cię czeka. Proponuję też lekturę artykułu Łukasza Lacha “PHP - Bezpieczne programowanie - Cross-Site Scripting”.
- Jeśli Twój filtr usuwa lub zmienia jakiś fragment danych, wstaw go w pętlę. Zmiana mogła spowodować zamianę szkodliwego kodu na inny, również niebezpieczny. Niech filtrowanie trwa tak długo, aż kolejny obrót pętli nie wykryje żadnych niebezpiecznych elementów. Dość dobrą praktyką jest zamiana szkodliwego kodu na jakiś tekst nie zawierający znaków specjalnych.
- Nie używaj strip_tags(), jeśli efekt działania tej funkcji nie jest naprawdę zgodny z Twoimi oczekiwaniami. Pamiętaj, by po strip_tags() użyć dodatkowo htmlspecialchars() + ENT_QUOTES.
- Przetestuj cały serwis. Pojedyncza luka XSS powoduje podatność całej domeny na ataki tego typu. Jeśli robisz to ręcznie, przydatne narzędzia to między innymi rozszerzenia do Firefoksa: Web Developer, Greasemonkey, ModifyHeaders, TamperData i wiele innych. Większy serwis można testować komercyjnym skanerem lub własnym skryptem. Jeśli nie jesteś pewien, czy Twoje testy są wystarczające, poszukaj specjalisty.
- Śledź na bieżąco nowości w dziedzinie bezpieczeństwa aplikacji WWW. Wciąż pojawiają się nowe metody ataków i omijania filtrów. Jest też bardzo prawdopodobne, że Twój serwis będzie narażony na ataki w wyniku luk w oprogramowaniu po stronie użytkownika (np. mhtml-redirect w IE lub UXSS w Acrobat Reader).
Leave a Comment
Bardzo fajny tekst :)