LAB_01 / BAZA DANYCH Podstawowy

Zapytania pod Twoją kontrolą. Poznaj granicę między danymi a kodem.

Wskazówka do eksperymentu

Najpierw sprawdź zwykłe dane wejściowe. Następnie użyj przykładu z lekcji i porównaj wynik w wariancie podatnym oraz zabezpieczonym. W panelach kodu zaznaczono miejsca istotne dla ataku lub obrony.

SQL Injection

01 / TEORIA · ⚠ PODATNY KOD

Podatny wariant

SQL Injection to technika, która pozwala atakującemu manipulować zapytaniami SQL, które są wykonywane przez aplikację. Atakujący może wykorzystać to do obejścia uwierzytelniania, wyświetlenia, modyfikacji lub usunięcia danych w bazie danych.

W podatnym wariancie dane wprowadzone przez użytkownika są bezpośrednio wstawiane do zapytania SQL. Na przykład, w metodzie sprawdzającej dane logowania


public function getUnsafe($username, $password) {
    $stmt = $this->pdo->query("SELECT * FROM users WHERE username = '$username' AND password = '$password'");
    return $stmt->fetch(); 
}
                    
zapytanie SQL jest tworzone przez konkatenację ciągu z danymi wprowadzonymi przez użytkownika. Jeśli atakujący wprowadzi wartości, które zmieniają strukturę zapytania SQL, może to prowadzić do niezamierzonych konsekwencji.
Metoda getUnsafe zwraca wynik zapytania SQL jako tablicę asocjacyjną, gdzie klucze są nazwami kolumn w wyniku zapytania SQL. W tym przypadku, zapytanie SQL to
SELECT * FROM users WHERE username = '$username' AND password = '$password'     
Wynik zawiera wszystkie kolumny tabeli users dla użytkownika pasującego do nazwy i hasła. Metoda getUnsafe jest podatna na SQL Injection, więc odpowiednio przygotowane dane mogą zmienić logikę zapytania. Wprowadź poniższy payload, czyli dane wejściowe przygotowane do zademonstrowania podatności:
 ' or ''='  
jako nazwę użytkownika i hasło. Zmieniony warunek może zwrócić pierwszy rekord użytkownika mimo nieprawidłowych danych logowania.

02 / ATAK · PRZETESTUJ DANE WEJŚCIOWE

03 / OBRONA · ✓ ZABEZPIECZONY KOD

Zabezpieczony wariant

W zabezpieczonym wariancie, dane wprowadzone przez użytkownika są parametryzowane, co oznacza, że są traktowane wyłącznie jako dane, a nie część zapytania SQL. Na przykład, w metodzie zabezpieczonej, która sprawdza dane logowania


public function getSafe($username, $password) { 
    $stmt = $this->pdo->prepare('SELECT * FROM users WHERE username = ? AND password = ?'); 
    $stmt->execute([$username, $password]); 
    return $stmt->fetch();
 } 
                    
zapytanie SQL jest przygotowywane z miejscami na parametry, które są później wypełniane danymi wprowadzonymi przez użytkownika. To zapobiega manipulacji struktury zapytania SQL przez atakującego.


Parametryzacja zapytań SQL jest zdecydowanie lepsza, ponieważ zapobiega atakom SQL Injection. Nawet jeśli atakujący próbuje wprowadzić wartości, które zmieniają strukturę zapytania SQL, te wartości są traktowane jako dane, a nie jako część zapytania SQL. To oznacza, że atakujący nie może manipulować zapytaniem SQL wykonywanym przez aplikację.

Dodawanie użytkowników