Przyczyną takiego zachowania PHP jest opcja magic_quotes_gpc ustawiona na On w php.ini. Stosuje się ją aby zabezpieczyć aplikację przed atakiem SQL Injection w razie, gdyby programista gdzieś zapomniał o przefiltrowaniu danych od użytkownika które potem wykorzystywane są w zapytaniach SQL (o tym później). Aby usunąć ze zmiennych POST czy GET niepotrzebne znaki backslash stosujemy funkcję stripslashes(). Usuwa ona znaki ucieczki '\' z ciągu podanego jako argument.
Kod:
<?php
$tresc = $_POST['tresc'];
$tresc = stripslashes($tresc);
echo $tresc;
?>
Warto wspomnieć, że odwrotną funkcjonalność do stripslashes() ma addslashes() która to dodaje znaki backslash przed znaki cudzysłowu w ciągu podanym jako parametr.
Kod:
<?php
$tresc = 'Zachęcamy do przeczytania książki pt. "Ala i jej kot".';
$tresc = addslashes($tresc);
echo $tresc;
?>
Wynikiem będzie taki ciąg znaków:
Zachęcamy do przeczytania książki pt. \"Ala i jej kot\".
A więc jak widać gdy opcja magic_quotes_gpc w php.ini jest ustawiona na On to PHP automatycznie przepuszcza wszystkie zmienne z tablic superglobalnych takich jak POST czy GET przez funkcję addslashes(). A po co w ogóle stosujemy addslashes ?
Kod:
<?php
// nawiązujmy połączenie z bazą danych
mysql_connect('localhost', 'root', '');
mysql_select_db('baza');
// pobieramy wszystkie rekordy z `username` równym
// takie jakie podał użytkownik w formularzu
$result = mysql_query("SELECT id FROM users WHERE username = '".$_GET['nick']."'");
// jeśli liczba pobranych rekordów jest większa od 0
// oznacza to, że odwiedzający podał poprawny username
// i zostaje zalogowany
if(mysql_num_rows($result) > 0)
echo 'jesteś zalogowany';
else
echo 'nie poprawny username';
?>
Jest to przykład prostego logowania. Zauważ, że nie użyliśmy tu funkcji addslashes() na zmiennej pochodzącej od użytkownika $_GET['nick']. Co się stanie jeśli odwołamy się do skryptu w ten sposób:
www.strona.com/skrypt.php?nick='%20OR%20username%20!=%20'
Użytkownik otrzyma nie autoryzowany dostęp do części strony. Dzięki odpowiedniemu spreparowaniu zmiennej tak zmodyfikował zapytanie SQL, że pobrało one wszystkie rekordy z bazy (puste lub nie puste). Potem mysql_num_rows() zwraca liczbę tych rekordów, a że jest ona na pewno większa od 0 odwiedzający otrzymał nieuprawniony dostęp. Gdybyśmy zastosowali addslashes() lub gdyby opcja magic_quotes_gpc była ustawiona na On wszystkie znaki cudzysłowu (które mysql rozpoznaje jako znaki składni zapytania) zostałyby oznaczone jako nic nieznaczące i ostatecznie odwiedzający nie miałby możliwości uzyskania dostępu do ukrytej części strony. Przykład poprawnego kodu:
Kod:
<?php
// nawiązujmy połączenie z bazą danych
mysql_connect('localhost', 'root', '');
mysql_select_db('baza');
// pobieramy wszystkie rekordy z `username` równym takie
// jakie podał użytkownik w formularzu
$nick = addslashes($_GET['nick']);
$result = mysql_query("SELECT id FROM users WHERE username = '$nick'");
// jeśli liczba pobranych rekordów jest większa od 0
// oznacza to, że odwiedzający podał poprawny username
// i zostaje zalogowany
if(mysql_num_rows($result) > 0)
echo 'jesteś zalogowany';
else
echo 'nie poprawny username';
?>