Skip to content

SQL Injection - idea ataku i jak się bronic

This content is not available in your language yet.

Co przekazesz słuchaczom?

Słuchacze zrozumieja, na czym polega atak SQL Injection, dlaczego jest jednym z najgroźniejszych zagrożeń dla aplikacji webowych, oraz jak się przed nim chronić za pomoca prepared statements. Poznaja różnicę miedzy niebezpiecznym a bezpiecznym kodem.

  1. Wprowadzenie (2 min) - Czym jest SQL Injection i dlaczego jest grozny
  2. Teoria: Mechanizm ataku (2 min) - Jak konkatenacja umozliwia atak
  3. Teoria: Skutki i rodzaje (2 min) - Co może zrobic atakujacy
  4. Demo praktyczne (4 min) - Podatny kod vs bezpieczny kod
  5. Podsumowanie (2 min) - Prepared statements i dobre praktyki

Mieszanie kodu i danych w jednym stringu

SQL Injection wystepuje, gdy dane od użytkownika sa bezposrednio wstawiane do zapytania SQL bez odpowiedniego zabezpieczenia. Atakujacy może wstrzyknac własne polecenia SQL.

// NIEBEZPIECZNY KOD - przykład do prezentacji
$username = $_POST['username'];
$query = "SELECT * FROM users WHERE username = '$username'";

Jeśli użytkownik wpisze: ' OR '1'='1

Zapytanie staje się:

SELECT * FROM users WHERE username = '' OR '1'='1'

To zapytanie zwroci WSZYSTKICH użytkowników!

Wyniki ataku widoczne bezposrednio w odpowiedzi:

UNION-based:

-- Atakujacy wpisuje w polu wyszukiwania:
' UNION SELECT username, password FROM users--
-- Zapytanie staje się:
SELECT name, price FROM products WHERE name = ''
UNION SELECT username, password FROM users--'

Error-based:

  • Atakujacy celowo wywołuje błędy SQL
  • Komunikaty błędów ujawniaja informacje o bazie
  • Np. nazwy tabel, kolumn, wersje bazy

Kradzież danych

  • Wyciagniecie wszystkich danych z bazy
  • Dostep do haseł, e-maili, danych osobowych
  • Dane kart kredytowych, numery PESEL

Modyfikacja danych

  • Zmiana haseł użytkowników
  • Modyfikacja cen produktow
  • Wstawienie złośliwych danych

Usuniecie danych

  • DROP TABLE users
  • DELETE FROM orders
  • Zniszczenie całej bazy danych

Przejecie systemu

  • Wykonanie polecen systemowych
  • Odczyt/zapis plikow na serwerze
  • Pełna kontrola nad serwerem

Bezpieczne zapytania z parametrami:

<?php
// Połączenie z baza przez PDO
$pdo = new PDO('mysql:host=localhost;dbname=app', 'user', 'pass');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// BEZPIECZNE - prepared statement
$stmt = $pdo->prepare('SELECT * FROM users WHERE username = :username');
$stmt->execute(['username' => $_POST['username']]);
$user = $stmt->fetch();
// Alternatywna składnia z ?
$stmt = $pdo->prepare('SELECT * FROM users WHERE username = ? AND active = ?');
$stmt->execute([$_POST['username'], 1]);

Dlaczego to działa:

  • Zapytanie jest najpierw kompilowane (struktura)
  • Potem dane sa wstawiane jako wartości
  • Dane NIGDY nie sa interpretowane jako kod SQL

Diagram pokazujacy:

  1. Użytkownik wpisuje dane w formularz
  2. Dane sa wklejane do stringa SQL
  3. Baza wykonuje “zmodyfikowane” zapytanie
  4. Atakujacy otrzymuje nieautoryzowane dane

Prosty przykład:

Oczekiwane: SELECT * FROM users WHERE name = 'Jan'
Atak: SELECT * FROM users WHERE name = '' OR '1'='1'
^^^^^^^^^^^^^^
Wstrzykniety kod!

Diagram dwuetapowy:

  1. Kompilacja: SELECT * FROM users WHERE name = ? (struktura)
  2. Wykonanie: Wstaw ‘Jan’ jako DANE (nie kod)

Ikony z opisami:

  • Ikona bazy -> “Cała baza wykradziona”
  • Ikona koszyka -> “Ceny zmienione na 0 zl”
  • Ikona smietnika -> “DROP TABLE users”
  • Ikona hakera -> “Pełna kontrola nad serwerem”
  1. Pokaz prosty formularz logowania
  2. Zaloguj się normalnie (użytkownik: admin, hasło: admin123)
  3. Pokaz podatny kod PHP
  4. Wpisz w pole username: ' OR '1'='1
  5. Pokaz, że logowanie przeszło bez hasła!
<?php
// PODATNY KOD - tylko do demonstracji!
$pdo = new PDO('mysql:host=localhost;dbname=demo', 'root', '');
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = $_POST['username'];
$password = $_POST['password'];
// NIEBEZPIECZNE!
$query = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";
echo "<pre>Zapytanie: $query</pre>";
$result = $pdo->query($query);
$user = $result->fetch();
if ($user) {
echo "<h2>Zalogowano jako: " . htmlspecialchars($user['username']) . "</h2>";
} else {
echo "<h2>Błędne dane logowania</h2>";
}
}
?>
<form method="POST">
<input name="username" placeholder="Username"><br>
<input name="password" type="password" placeholder="Password"><br>
<button>Login</button>
</form>
  1. Pokaz ten sam formularz z prepared statements
  2. Sprobuj tego samego ataku
  3. Pokaz, że atak nie działa
  4. Wyjasni dlaczego prepared statements sa bezpieczne
<?php
// BEZPIECZNY KOD
$pdo = new PDO('mysql:host=localhost;dbname=demo', 'root', '');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = $_POST['username'];
$password = $_POST['password'];
// BEZPIECZNE - prepared statement
$stmt = $pdo->prepare('SELECT * FROM users WHERE username = ? AND password = ?');
$stmt->execute([$username, $password]);
$user = $stmt->fetch();
if ($user) {
echo "<h2>Zalogowano jako: " . htmlspecialchars($user['username']) . "</h2>";
} else {
echo "<h2>Błędne dane logowania</h2>";
}
}
?>
<form method="POST">
<input name="username" placeholder="Username"><br>
<input name="password" type="password" placeholder="Password"><br>
<button>Login</button>
</form>
  1. Pokaz wyszukiwarke produktow
  2. Wpisz: ' UNION SELECT username, password FROM users--
  3. Pokaz, że atakujacy widzi hasła użytkowników
  4. Omow jak przygotowane zapytanie to blokuje

Wymagania minimalne:

  • Wyjasnij idee ataku SQL Injection
  • Pokaz 1 przykład “zły kod vs dobry kod”
  • Pokaz 1 schemat przepływu ataku
Ocena: 3.0 (minimum)

Pytanie 1

Dlaczego prepared statements sa odporne na SQL Injection?

Pytanie 2

Czy walidacja danych wejsciowych (np. sprawdzenie czy to liczba) wystarczy jako ochrona?

Pytanie 3

Co to jest zasada “least privilege” i jak pomaga w ograniczeniu skutkow ataku?

Pytanie 4

Jak chronić dynamiczne nazwy kolumn w zapytaniach ORDER BY?

Prepared Statements

Zawsze uzywaj parametryzowanych zapytan. To podstawowa i najważniejsza obrona.

Walidacja wejscia

Sprawdzaj typy i format danych. Liczba powinna być liczba, email powinien być e-mailem.

Least Privilege

Aplikacja powinna mieć minimalne uprawnienia. Tylko SELECT, INSERT, UPDATE, DELETE - nie DROP, CREATE.

Ukrywanie błędów

Na produkcji nie pokazuj komunikatow o błędach SQL. Loguj je, ale nie wyswietlaj.