Szczerze mówiąc, myślę, że autor tych funkcji albo nie ma pojęcia, czym są iniekcje XSS i SQL, ani co dokładnie robi użyta funkcja.
Wystarczy wymienić dwie osobliwości:
- Korzystanie z
stripslashes
pomysql_real_escape_string
usuwa ukośniki dodane przezmysql_real_escape_string
. htmlentities
zastępuje chatacters<
i> które są używane w
strip_tags
w celu identyfikacji tagów.
Ponadto:Generalnie funkcje chroniące przed XSS nie nadają się do ochrony przed wstrzyknięciami SQL i na odwrót. Ponieważ każdy język i kontekst ma swoje własne znaki specjalne, o które należy zadbać.
Moja rada to dowiedzieć się, dlaczego i jak możliwe jest wstrzykiwanie kodu oraz jak się przed nim chronić. Naucz się języków, z którymi pracujesz, zwłaszcza znaków specjalnych i sposobów ich unikania.
Edytuj Oto (prawdopodobnie dziwny) przykład:wyobraź sobie, że pozwalasz użytkownikom na wprowadzenie pewnej wartości, która powinna być użyta jako segment ścieżki w identyfikatorze URI, którego używasz w kodzie JavaScript w onclick
wartość atrybutu. Kontekst językowy wygląda więc tak:
- Wartość atrybutu HTML
- Ciąg JavaScript
- Segment ścieżki URI
- Ciąg JavaScript
I żeby było fajniej:przechowujesz tę wartość wejściową w bazie danych.
Teraz, aby poprawnie przechowywać tę wartość wejściową w swojej bazie danych, wystarczy użyć odpowiedniego kodowania dla kontekstu, w którym zamierzasz wstawić tę wartość do języka bazy danych (np. SQL); reszta nie ma znaczenia (jeszcze). Ponieważ chcesz wstawić go do deklaracji ciągu SQL, kontekstowe znaki specjalne są znakami, które umożliwiają zmianę tego kontekstu. Jeśli chodzi o deklaracje ciągów, te znaki to (zwłaszcza) "
, '
i \
postacie, które należy uciec. Ale jak już wspomniano, przygotowane oświadczenia robią wszystko, co działa dla Ciebie, więc używaj ich.
Teraz, gdy masz już wartość w swojej bazie danych, chcemy ją poprawnie wyprowadzić. Tutaj przechodzimy od najbardziej wewnętrznego do zewnętrznego kontekstu i stosujemy właściwe kodowanie w każdym kontekście:
- Dla segmentu ścieżki URI kontekst musimy uciec (przynajmniej) od wszystkich tych znaków, które pozwalają nam zmienić ten kontekst; w tym przypadku
/
(pozostaw bieżący segment ścieżki),?
i#
(oba opuszczają kontekst ścieżki identyfikatora URI). Możemy użyćrawurlencode
za to. - Dla ciągu JavaScript kontekst, o który musimy zadbać
"
,'
i\
. Możemy użyćjson_encode
w tym celu (jeśli jest dostępny). - Dla wartości atrybutu HTML musimy zadbać o
&
,"
,'
i<
. Możemy użyćhtmlspecialchars
za to.
Teraz wszystko razem:
'… onclick="'.htmlspecialchars('window.open("http://example.com/'.json_encode(rawurlencode($row['user-input'])).'")').'" …'
Teraz, jeśli $row['user-input']
to "bar/baz"
wyjście to:
… onclick="window.open("http://example.com/"%22bar%2Fbaz%22"")" …
Ale używanie wszystkich tych funkcji w tych kontekstach nie jest przesadą. Ponieważ chociaż konteksty mogą mieć podobne znaki specjalne, mają różne sekwencje specjalne. URI ma tak zwane kodowanie procentowe, JavaScript ma sekwencje specjalne, takie jak \"
a HTML ma odwołania do znaków, takie jak "
. A nieużywanie tylko jednej z tych funkcji pozwoli na przerwanie kontekstu.