4.2 SQL Injection

SQL Injection (SQLi) umožňuje útočníkovi zasahovat do SQL dotazů, které aplikace provádí proti své databázi.

Základní princip

Útočník upraví strukturu dotazu nebo může spustit dotazy navíc, pokud aplikace spojuje řetězce a nevhodně ošetřuje uživatelský vstup.

Zranitelný přihlašovací kód
SELECT * FROM users
WHERE username = '$username'
AND password = '$password'

Pokud je username nastaven na x' OR 1 = 1 --, dotaz se vyhodnotí takto:

SELECT * FROM users
WHERE username = 'x' OR 1 = 1 --' AND password = '...'

Podmínka 1 = 1 je pravdivá a znaky -- tvoří komentář. Dotaz přihlásí útočníka k prvnímu (často admin) uživateli.

Spuštění více dotazů a databázové schéma

Dle použité databáze a klienta může být k dispozici spouštění více dotazů najednou (např. ; DROP TABLE users --). K identifikaci názvů tabulek může útočník číst tabulku metadat jako information_schema.tables. Pomocí klauzule UNION ALL je zase možné kombinovat výstupy dalších dotazů, pokud je zobrazen pouze jeden výsledek.

Blind SQL Injection

Typy Blind SQL Injection

Někdy nejsou výsledky vraceny vůbec. V takových případech nastupuje Blind SQL Injection:

  • Boolean-based: Odlišná odpověď stránky na dotazy vedoucí na True/False umožňuje znak po znaku extrahovat data pomocí binárního vyhledávání.
  • Error-based: K rozeznání True/False se využívá vyvolání chyby SQL databáze.
  • Time-based: Vyvolání funkce (např. SLEEP()) přiřadí specifickému stavu dlouhou dobu odezvy, a tím ho útočník rozezná.
  • Out-of-band: Extrakce informací vyvoláním asynchronní komunikace na server ovládaný útočníkem (např. přes DNS/HTTP request).
Countermeasures (Obrana)
  • Prepared statements: Nejspolehlivější metoda obrany. Samotná SQL struktura a předaná data (parametry) jsou od sebe striktně oddělené už v databázi.
  • V případech, kde Prepared statements nelze využít (např. dynamické zadávání jména sloupce v ORDER BY), je třeba název mapovat k bezpečnému whitelistu.