4.2 SQL Injection
SQL Injection (SQLi) umožňuje útočníkovi zasahovat do SQL dotazů, které aplikace provádí proti své databázi.
Ú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.
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
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).
- 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.