(Nie)bezpieczny kod – SQL Injection

Zobacz na czym polega ten atak i jak się przed nim zabezpieczyć.

SQL Injection ­– jest techniką ataku starą jak świat. Mimo tego wciąż jest niestety dość powszechną i prostą metodą ataku na strony www (nawet na te największe jak portale). Dzieje się tak, ponieważ przy tej metodzie najsłabszym ogniwem jest programista. Zobacz na czym polega ten atak i jak się przed nim zabezpieczyć.

 

Trochę teorii

SQL Injection polega na wstrzyknięciu kodu SQL w zapytanie wysyłane do bazy danych. Dzięki użyciu znaków specjalnych (apostrof, cudzysłów itp.) można dowolnie zmodyfikować treść zapytania.

 

Przykładowy atak SQL Injection

Myślę, że analiza przykładowego ataku pokaże o co chodzi w SQL Injection. Jako przykład posłuży nam prosty skrypt logowania użytkownika.

 

Na początek przygotuj strukturę bazy danych:

Tworzę tabelę admin zawierającą 3 kolumny (id, login, password) i dodaję 2 administratorów. Tak wygląda gotowa struktura bazy danych:

 

Baza danych gotowa, teraz pora na formularz:

Jest to standardowy formularz HTML z dwoma polami: loginem i hasłem. 99% formularzy do logowania tak wygląda.

 

Baza i formularz gotowe, pora na skrypt PHP:

 

Do połączenia z bazą danych korzystam z biblioteki PDO. Jeżeli jej nie znasz odsyłam do dokumentacji – http://php.net/manual/en/book.pdo.php

 

Jest to bardzo proste zapytanie z dwoma warunkami. Zwróć uwagę, że wartość zmiennych pochodzi bezpośrednio z tablicy $_POST.

 

Za pierwszym razem próbuję zalogować się na dane: login: admin, password: hasla nie znam. Jak widać poniżej, skrypt zachowuje się zgodnie z oczekiwaniami. Podałem błędne dane, a więc nie loguje.

Co będzie w sytuacji, gdy wpiszę login: admin, password: ‚ OR 1 = ‚1? Powinno mnie nie zalogować, ale…

 

 

Jak widać zalogowałem się bez problemu. Istotą tego ataku jest warunek logiczny OR 1=1. Wykorzystując fakt, że mogę do zapytania wstrzyknąć dowolny kod (wraz z apostrofami) stwarzam sytuację, gdy dane zapytanie jest zawsze prawdziwe – prawda/fałsz LUB prawda zawsze zwróci prawdę.

 

Oczywiście nic nie stoi na przeszkodzie, by wstrzyknąć inny kod SQL, na przykład usuwający dane z jakieś tabeli.

 

Jak się zabezpieczyć przed SQL Injection?

 

Na szczęście istnieje prosty sposób na zabezpieczenie się przed tym atakiem. Wystarczy przed każdym znakiem specjalnym dodać znak „\”. Do tego celu PDO udostępnia odpowiednie metody.

 

 

Jeżeli korzystasz z PDO wystarczy każdą zmienną przekazać do zapytania za pomocą metody bindValue(). Metoda ta przeparsuje odpowiednio wartość zmiennej.

 

Gdy wpiszę teraz login: admin, password: ‚ OR 1=1 skrypt zwróci:

 

 

Czyli zachowuje się zgodnie z przewidywaniami – podano błędne dane, a więc nie loguje użytkownika. Jeżeli podam poprawne dane skrypt zaloguje użytkownika.

 

 

Uwaga: informacje przedstawione w artykule służą tylko celom edukacyjnym. ZABRONIONE jest wykorzystywanie informacji przedstawionych w artykule do celów niezgodnych z prawem. Autor nie ponosi odpowiedzialności za ewentualne szkody.

 

Autor: Kamil Michaliszyn


Opublikowano:

Mentax na Facebook'u