SQL injection
Z Wikipedie, otevřené encyklopedie
| Tento článek obsahuje informace, které nejsou ověřené. Jste-li s předmětem článku dostatečně seznámen, opravte, prosíme, nepřesnosti a doplňte prameny (literaturu apod.), které dokládají uvedená tvrzení. |
SQL injection je technika napadení databázové vrstvy programu vsunutím (odtud „injection“) kódu přes neošetřený vstup a vykonání vlastního, samozřejmě pozměněného, SQL dotazu. Toto nechtěné chování vzniká při propojení aplikační vrstvy s databázovou vrstvou (téměř vždy se totiž jedná o dva různé programy) a zabraňuje se mu pomocí jednoduchého escapování potencionálně nebezpečných znaků.
Obsah |
[editovat] SQL injection a web
V klasickém případě je útok na internetové stránky prováděn přes neošetřený formulář, manipulací s URL nebo třeba i podstrčením zákeřně upravené cookie. Bohužel, na internetu je stále velké množství webů, spravovaných převážně nezkušenými programátory, kteří o této technice útoku prostě neví a tuto kritickou chybu opomíjejí.
[editovat] Ukázka útoku
Mějme program odesílající dotaz do databáze:
statement := "SELECT * FROM uzivatele WHERE jmeno = '" + zadaneJmeno + "';"
Pokud však uživatel zadá jako jméno například:
a' or 'b'='b
aplikační program dotaz doplní a odešle databázi ve formě
statement := "SELECT * FROM uzivatele WHERE jmeno = 'a' or 'b'='b';"
což může zapříčinit přemostění autorizační procedury, protože 'b' = 'b' je vždy pravda.
Pro SQL injection se samozřejmě dají použít všechny dostupné příkazy, pokud bychom tedy v předešlém příkladě jako jméno zadali
a';DROP TABLE uzivatele; --
vypadal by dotaz při odeslání serveru jako
statement := "SELECT * FROM uzivatele WHERE jmeno = 'a';DROP TABLE uzivatele; --';"
čímž se nám povedlo smazat celou tabulku uživatelů. Poslední apostrof je pomocí sekvence – zapoznámkován a nemá žádý vliv.
Podobných průniků je samozřejmě celá řada, díky klauzulím UNION a JOIN nejsme ani vázáni na tabulku předepsanou v části FROM a můžeme vypisovat data odkudkoliv z databáze.
[editovat] Obrana
[editovat] Na straně aplikace
Nejjednodušší obrana spočívá ve vhodné kontrole a úpravě vstupních dat. Prakticky každý skriptovací program s podporou databáze má nějakou vestavěnou funkci pro převedení potenciálně nebezpečných znaků na bezpečnou sekvenci. Tuto funkci je možné použít před vytvořením dotazu.
Například pro Perl
$query = $sql->prepare( "SELECT * FROM uzivatele WHERE jmeno = " . $sql->quote($zadaneJmeno) );
pro PHP (v příkladu implementace MySQL):
$sql = "SELECT * FROM uzivatele WHERE jmeno = " . mysql_real_escape_string($zadaneJmeno); mysql_query($sql);
Dalším bezpečnostním opatřením (může se stát, že na ošetření vstupu někde prostě zapomeneme), je vypnutí vypisování chyb. Pokud by pak útočník na nějaký napadnutelný vstup narazil, nedozví se o tom z chybových hlášení.
[editovat] Na straně databáze
V databázi můžeme útoku zabránit (nebo ho přinejmenším extrémně ztížit) vhodným nastavením práv uživatele, se kterými bude program přistupovat. Málokdy je třeba přímo z aplikační vrstvy mazat tabulky či dokonce databáze, proto stačí povolit jen základní SQL příkazy.

