SQL injectionSQL injection je technika napadnutia databázovej vrstvy aplikácie, spočívajúca vo vsunutí (odtiaľ „injection“) kódu prostredníctvom neošetreného alebo nesprávne ošetreného vstupu a vykonaní vlastného SQL príkazu. Týka sa tak webových ako aj všetkých ostatných aplikácií pracujúcich s databázami. Zneužitie môže viesť k získaniu citlivých údajov, ako napr. prihlasovacie údaje, osobné údaje (čísla bankových účtov, rodné čísla...); pozmeneniu, doplneniu alebo odstráneniu údajov, prípadne aj k ovládnutiu celého serveru.[1][2] Popis jazyka SQLSQL je skratka pre Structured Query Language, teda štrukturovaný jazyk používaný v databázach pre prácu s dátami.
SQL príkazy sú používané pre vykonanie príkazov, ktoré menia databázu. Môžu napr. aktualizovať, získavať alebo pridávať dáta do databázy.
Medzi rôzne databázové systémy patria: Oracle, Sybase, Microsoft SQL Server, Access, Ingres atď. Väčšina SQL príkazov sa skladá zo štandardných príkazov Zneužitie prihlasovacieho formuláraPrihlasovacie formuláre väčšinou využívajú databázu pre overenie alebo pridanie odosielaných dát. Klasický príklad na príkaz ktorý pri prihlasovaní overí či je daný užívateľ v databáze by mohol vyzerať v php napr. takto: SELECT * FROM uzivatelia WHERE meno = '$zadaneMeno' AND heslo='$zadaneHeslo';
Pri vložení do zadaneMeno apostrofu ' vznikne SQL príkaz ktorý skončí chybou. Pokiaľ však je vložený do zadaneMeno SQL komentár spolu s apostrofom a účtom za ktorý chce byť útočník prihlásený („admin'--“) vznikne príkaz, ktorý neoveruje správnosť zadaného hesla a útočník sa môže týmto spôsobom napr. prihlásiť do systému bez toho, že by vedel heslo. SELECT * FROM uzivatelia WHERE meno = 'admin'--' AND heslo='';
Podobný výsledok sa dá dosiahnuť použitím operátorov OR a AND zadaním za heslo „' OR 1=1--“: SELECT * FROM uzivatelia WHERE meno = '$zadaneMeno' AND heslo='' OR 1=1--';
Keďže 1=1 je pravda vždy tak môže útočník zadať akékoľvek heslo a vždy bude prihlásený do systému. Ochrana na strane aplikáciePriamočiary prístup, ako zabrániť SQL injection, je takzvané „escapovanie“ znakov, ktoré majú špeciálny význam v SQL. Napríklad každý výskyt apostrofu (') môže byť nahradený dvoma úvodzovkami pre vytvorenie valídneho reťazca. Napr. v php sa pre takéto escapovanie používa funkcia mysql_real_escape_string() ešte pred odoslaním príkazu do databázy.[2] Príklad v jazyku Perl $query = $sql->prepare("SELECT * FROM uzivatelia WHERE meno = ". $sql->quote($zadaneMeno));
Príklad v jazyku PHP a MySQLi [4]$mysqli = @mysqli_connect(db_hostname, db_username, db_password, db_name); //otvorenie nového spojenia do MySQL
$val1 = mysqli_real_escape_string($mysqli, $_POST["va1"]); //escapuje nepovolené znaky zo superglobálnej premennej
$val2 = mysqli_real_escape_string($mysqli, $_GET["va1"]); //escapuje nepovolené znaky zo superglobálnej premennej
$query = sprintf("SELECT * FROM `uzivatelia` WHERE value1='%s' AND value2='%s'", $val1, $val2); //vytvorí dopyt s už overenými hodnotami
$result = mysqli_query($mysqli, $query); //vracia výsledok dopytu
Takto môže vyzerať ošetrený kód proti sql injection útoku. Vstupné premenné sú ošetrené pomocou funkcie mysqli_real_escape_string(mysqli $mysqli, string $escapestr), ktorá pridá spätnú lomku znakom \x00, \r, \n, \, ',, a \x1a. Táto funkcia by mala byť použitá pri každom dopyte do databázy, avšak občas je zbytočná – napr. pri premennej ktorá ma dátový typ (int). Príklad v jazyku PHP a Oracle$stmt = oci_parse($connOci, 'SELECT * FROM LOGIN WHERE jmeno = :login');
oci_bind_by_name($stmt, ':login', $_POST['login']);
oci_execute($stmt);
Existuje veľa ďalších rôznych funkcií v PHP pre ochranu proti SQLi špecifických pre rôzne databázy, napr. pg_escape_string() pre PostgreSQL. Pozri ajReferencie
Externé odkazy
|