Bezpieczeństwo to ciekawa koncepcja i przyciąga do niej wiele osób. Niestety jest to złożony temat i nawet profesjonaliści się mylą. Znalazłem luki w zabezpieczeniach w Google (CSRF), Facebooku (więcej CSRF), kilku głównych sklepach internetowych (głównie wstrzykiwanie SQL / XSS), a także tysiącach mniejszych witryn, zarówno korporacyjnych, jak i osobistych.
Oto moje rekomendacje:
1) Użyj zapytań parametrycznych
Sparametryzowane zapytania wymuszają traktowanie wartości przekazanych do zapytania jako oddzielnych danych, tak aby wartości wejściowe nie mogły zostać przetworzone przez SZBD jako kod SQL. Wiele osób zaleca, aby zmienić ciąg znaków za pomocą mysql_real_escape_string()
, ale wbrew powszechnemu przekonaniu nie rozwiązanie typu catch-all do wstrzykiwania SQL. Weźmy na przykład to zapytanie:
SELECT * FROM users WHERE userID = $_GET['userid']
Jeśli $_GET['userid']
jest ustawiony na 1 OR 1=1
, nie ma znaków specjalnych i nie będzie filtrowany. Powoduje to zwrócenie wszystkich wierszy. Lub, co gorsza, co jeśli jest ustawiony na 1 OR is_admin = 1
?
Zapytania sparametryzowane zapobiegają tego rodzaju wstrzykiwaniu.
2) Zweryfikuj swoje dane wejściowe
Sparametryzowane zapytania są świetne, ale czasami nieoczekiwane wartości mogą powodować problemy z kodem. Upewnij się, że potwierdzasz, że znajdują się w zasięgu i że nie pozwolą bieżącemu użytkownikowi zmienić czegoś, czego nie powinni móc.
Na przykład możesz mieć formularz zmiany hasła, który wysyła żądanie POST do skryptu, który zmienia hasło. Jeśli umieścisz ich identyfikator użytkownika jako ukrytą zmienną w formularzu, mogą go zmienić. Wysyłam id=123
zamiast id=321
może oznaczać, że zmienią hasło innej osoby. Upewnij się, że WSZYSTKO jest poprawnie zweryfikowane pod względem typu, zasięgu i dostępu.
3) Użyj htmlspecialchars, aby uciec od wyświetlanych danych wprowadzanych przez użytkownika
Powiedzmy, że użytkownik wpisuje „o mnie” w następujący sposób:</div><script>document.alert('hello!');</script><div>
Problem polega na tym, że dane wyjściowe będą zawierać znaczniki wprowadzone przez użytkownika. Próba samodzielnego filtrowania tego za pomocą czarnych list to po prostu zły pomysł. Użyj htmlspecialchars
aby odfiltrować ciągi tak, aby znaczniki HTML zostały przekonwertowane na jednostki HTML.
4) Nie używaj $_REQUEST
Ataki polegające na fałszowaniu żądań między witrynami (CSRF) polegają na tym, że użytkownik klika łącze lub odwiedza adres URL reprezentujący skrypt, który wykonuje akcję w witrynie, w której jest zalogowany. $_REQUEST
zmienna jest kombinacją $_GET
, $_POST
i $_COOKIE
, co oznacza, że nie można odróżnić zmiennej, która została wysłana w żądaniu POST (tj. przez input
w formularzu) lub zmienną, która została ustawiona w adresie URL w ramach GET (np. page.php?id=1
).
Załóżmy, że użytkownik chce wysłać komuś prywatną wiadomość. Mogą wysłać żądanie POST do sendmessage.php
, z to
, subject
i message
jako parametry. Teraz wyobraźmy sobie, że zamiast tego ktoś wysyła żądanie GET:
sendmessage.php?to=someone&subject=SPAM&message=VIAGRA!
Jeśli używasz $_POST
, nie zobaczysz żadnego z tych parametrów, ponieważ są one ustawione w $_GET
zamiast. Twój kod nie zobaczy $_POST['to']
lub jakąkolwiek inną zmienną, więc nie wyśle wiadomości. Jeśli jednak używasz $_REQUEST
, $_GET
i $_POST
utkną razem, więc atakujący może ustawić te parametry jako część adresu URL. Gdy użytkownik odwiedza ten adres URL, nieumyślnie wysyła wiadomość. Naprawdę niepokojące jest to, że użytkownik nie musi nic robić. Jeśli atakujący utworzy złośliwą stronę, może ona zawierać iframe
który wskazuje na adres URL. Przykład:
<iframe src="http://yoursite.com/sendmessage.php?to=someone&subject=SPAM&message=VIAGRA!">
</iframe>
Powoduje to, że użytkownik wysyła wiadomości do ludzi, nawet nie zdając sobie sprawy, że cokolwiek zrobili. Z tego powodu należy unikać $_REQUEST
i użyj $_POST
i $_GET
zamiast tego.
5) Traktuj wszystko, co otrzymasz jako podejrzane (lub nawet złośliwe)
Nie masz pojęcia, co wysyła Ci użytkownik. To może być uzasadnione. To mógł być atak. Nigdy nie ufaj niczemu, co przesłał Ci użytkownik. Konwertuj na poprawne typy, weryfikuj dane wejściowe, używaj białych list do filtrowania w razie potrzeby (unikaj czarnych list). Obejmuje to wszystko, co zostało wysłane przez $_GET
, $_POST
, $_COOKIE
i $_FILES
.
Jeśli postępujesz zgodnie z tymi wytycznymi, masz rozsądną pozycję pod względem bezpieczeństwa.