Jump to content
Michael2318

Bezpieczeństwo skryptów PHP - SQL INJECTION

Recommended Posts

Michael2318

Ostatnio, przeglądając różnego rodzaju skrypty, czy to poradniki, czy to skrypty sprzedawane na allegro - wiele z tych skryptów jest po prostu dziurawych, webmasterzy zapominają o tym, że ich rozwiązania mogą stać się celem kogoś niepowołanego (czyt. hackera).

Najczęstszym zagrożeniem są ataki SQL INJECTION. Atak ten polega na zmianie zapytania SQL przez formularze lub linki w przeglądarkach. Każdy porządny serwis przechowuje masę danych w bazie. Jednak przy wyciąganiu tych danych zapominamy o (jak już wspomniałem) bezpieczeństwie! Teraz na szczęście hostingi same zabezpieczają nas przed brakiem podstawowych filtracji danych, ale nie można polegać tylko na tym, bo można się łatwo przejechać ;)
Przykładem wykorzystania ataku SQL INJECTION może być chociażby skrypt logowania oparty o bazę danych. Logując się na jakąś stronę, skrypt musi sprawdzić czy podane przez nas dane w formularzu, zgadzają się z danymi podanymi w bazie. Tak więc po uzupełnieniu słynnych pól Login & Hasło (dla przykładu L: admin / H: haslo) wykonywane jest mniej więcej takie zapytanie:

$sql = "SELECT * FROM `users` WHERE username = 'admin' AND user_password = 'haslo'"; 
$result = mysql_query($sql) 
or die('error');

Na pierwszy rzut oka nie ma tutaj nic podejrzanego. Jednak jeśli znamy jakikolwiek login/nick do serwisu, możemy w polu Login wpisać znany_nick'"; #. Co to spowoduje? A no zamieni nasze zapytanie z powyższego na:
 

$sql = "SELECT * FROM `users` WHERE username = 'znany_nick'"; #' AND user_password = 'haslo'"; 
$result = mysql_query($sql) 
   or die('error');

I co się stało? Wrzućmy powyższy kod do pierwszego lepszego edytora PHP:

deniJPG_rwwrhnw.JPG.4ef30eed3b3f64384244

Jak widać, druga część została zakomentowana, czyli nie będzie ona brana pod uwagę. Tak więc do bazy zostanie wykonane następujące zapytanie:

$sql = "SELECT * FROM `users` WHERE username = 'znany_nick'"; 
$result = mysql_query($sql) 
   or die('error');

I co teraz? A no to, że skrypt nie wykryje żadnych nieprawidłowości...Podaliśmy login, który w bazie istnieje, hasła w ogóle nie brało pod uwagę, więc co mu pozostało innego - musi nas zalogować na konto o wskazanym nicku.

Sprawa wyglądałaby zupełnie inaczej, gdyby użyć tutaj filtracji danych, czyli funkcji mysql_escape_string(). Co to da? Wzorując się na poprzednim przykładzie, jeśli "owiniemy"nasz poprzedni nick we wcześniej wskazaną funkcję, zapytanie przyjmie postać:
 

SELECT * FROM `users` WHERE username = 'znany_nick\'\"; #' AND user_password = 'haslo'; 
$result = mysql_query($sql) 
   or die('error');

Jak widać, funkcja dodała przed cudzysłowem i apostrofem slash'a\e, co w składni PHP wygląda już lepiej:

deniJPG_rwwrhex.JPG.f971c42f5fdbdf27a189


 Konkretniej, slash spowodował iż stojące obok niego cudzysłów i apostrof zostały zignorowane, a idąc dalej, płotek nie spowodował zakomentowania reszty ciągu. W tym wypadku do bazy leci zapytanie sprawdzające żywcem, czy w bazie istnieje user o nicku: znany_nick\'\"; #. Wiadome, że raczej nie istnieje, więc już z takiego myku co do logowania nici.

Ja polecam jeszcze od siebie dodanie preg_match() i po prostu zezwolić na wpisanie liter dużych, małych oraz cyfr, podobnie z rejestracją i tego typu znaki jak apostrofy, cudzysłowy itd. mamy z głowy ;)


Podobnie sytuacja wygląda w linkach stron. Przykładowo, w takim adresie: http://strona.pl/profil.php?id=144 liczba (konkretniej ID) na pewno ma coś wspólnego z bazą. I tutaj też, jeśli źle zabezpieczymy w plikach zmienne $_GET, nasz skrypt będzie dziurawy jak ser szwajcarski :) Podobnie jak wyżej, zamiast cyfry 144, tworzymy podobny ciąg znaków, jak ten wyżej, gdzie mowa była o skrypcie logowania. Efekt będzie ten sam. Dlatego w przypadku zmiennych $_GET, powinniśmy je zabezpieczać:

a ) w przypadku, gdy oczekujemy z GET'a liczby:

intval()

lub:

is_numeric()

b ) w przypadku, gdy oczekujemy z GET'a jakiegoś tekstu:

htmlspecialchars()

Podsumowując - przy pisaniu czegokolwiek, zwłaszcza zintegrowanego z bazą danych, musimy pamiętać przede wszystkim o bezpieczeństwie naszego skryptu. Jak widać, wystarczy dopisać jedną funkcję do zmiennych i cały skrypt staje się o wiele bezpieczniejszy :) 

Opis bezpieczeństwa skryptów PHP by Michael2318

  • Like 1

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.
×
×
  • Create New...