SQL Injection
Ukážka možného spôsobu útoku:
// $name - vstup klienta
$name = “ilia’; DELETE FROM users;”;
mysql_query(“SELECT * FROM users WHERE name=’{$name}’”);
Okrem výberu zoznamu užívateľov podľa zadaného parametra bude vymazaná tabuľka users.
Toto však neplatí pre MySQL pri volaní PHP funkcie mysql_query, ktorá nevykoná viacero SQL príkazov v jednom volaní (napr. SELECT a DELETE). Problém však nastane ak použijeme nové rozhranie PHP mysqli, kde je zabudované funcia pre vykonanie viacerých SQL príkazov. Taktiež napríklad databázy SQLite alebo PostgreSQL vykonajú obidva príkazy a nastane popísaný problém.
Magic Quotes
Riešením tohto problému je použitie PHP funkcií stripslashes() a mysql_real_escape_string() nasledujúcim spôsobom:
if (get_magic_quotes_gpc()) {
$name = stripslashes($name);
}
$name = mysql_real_escape_string($name);
mysql_query(“SELECT * FROM users WHERE name=’{$name}’”);
Ak escape nepomáha
Prípad, keď SQL príkaz očakáva celočíselnú hodnotu (integer):
// $name - vstup klienta
$id = “0; DELETE FROM users”;
$id = mysql_real_escape_string($id); // 0; DELETE FROM users
mysql_query(“SELECT * FROM users WHERE id={$id}”);
Riešenie je celkom jenoduché – skonvertovať vstup na typ integer operátorom (int) alebo funkciou intval():
$id = “123; DELETE FROM users”;
$id = (int) $id; // výsledok operácie = 123
mysql_query($conn, “SELECT * FROM users WHERE id={$id}”); // bezpečný príkaz
Spracovanie chybových hlásení SQL
Ošetrenie chýb pri vykonávaní príkazov SQL zabríni potencionálnym zvedavcom dozvedieť sa z týchto hlásení niečo o našej databáze. Tu je obvyklý spôsob výpisu chyby pri zlyhaní:
mysql_query($query) or die(“Failed query: {$query}<br />”.mysql_error());
Kedže tieto informácie môžu byť dôležité pre nás, je potrebné ich niekam ukladať, najjednoduchšou cestou je zapisovanie chybových hlásení do súboru Užívateľovi vypíšeme len bežné hlásenie o nedostupnosti údajov.
function sql_failure_handler($query, $error) {
$msg = htmlspecialchars(“Failed Query: {$query}<br>SQL Error: {$error}”);
error_log($msg, 3, “/home/site/logs/sql_error_log”);
if (defined(‘debug’)) {
return $msg;
}
return “Requested page is temporarily unavailable, please try again later.”;
}
mysql_query($query) or die(sql_failure_handler($query, mysql_error()));
| Guide to PHP security 3, 135.8 (kB) | ||
Generátor typoscriptu
Vytvára typoscript pre bežné použitie. Generátor je jednoduchý na obsluhu, stačí vyplniť zopár položiek formulára.