MySQL SQL Injection(注入)

 

若是經過網頁接收用戶輸入,然後再把這些數據插入到數據庫中,那麼你可能就會碰到 SQL 注入式攻擊。本節簡要介紹如何防範這種攻擊,確保腳本和 MySQL 語句的安全性。mysql

注入式攻擊每每發生在要求用戶輸入時,好比說要求他們輸入本身的名字,可是他們卻輸入了一段 MySQL 語句,不知不覺地運行在數據庫上。sql

永遠不要相信用戶所提供的數據,只有在驗證無誤後,才能去處理數據。一般,利用模式匹配來實現。在下面這個範例中,username(用戶名)被限定爲字母數字混合編制的字符串,再加上下劃線,長度限定爲8~20個字符之間。固然,能夠按須要修改這些規範。數據庫

if (preg_match("/^\w{8,20}$/", $_GET['username'], $matches))
{
   $result = mysql_query("SELECT * FROM users 
                          WHERE username=$matches[0]");
}
 else 
{
   echo "username not accepted";
}

爲了暴露問題所在,請考慮下面這段代碼:安全

// 本應該的輸入
$name = "Qadir'; DELETE FROM users;";
mysql_query("SELECT * FROM users WHERE name='{$name}'");

函數調用本來會從 users 表中獲取一個記錄。name 列與用戶所指定的名字所匹配。在通常狀況下,$name 會包含字母數字混合編制的字符,或許還包含空格,such as the string ilia. 但這裏,爲 $name 添加了一個全新的查詢,數據庫調用就變成了災難:注入的 DELETE 查詢會刪除 users 表中全部的記錄。markdown

幸運的是,若是使用 MySQL,mysql_query() 函數不容許堆疊查詢,或在一個函數調用中執行多個查詢。若是嘗試使用堆疊查詢,則調用會失敗。函數

然而,有些 PHP 數據庫擴展,好比 SQLite 或 PostgreSQL,卻能很好地執行堆疊查詢,可以執行一個字符串中所提供的全部查詢,從而形成嚴重的安全隱患。code

防止 SQL 注入式攻擊

使用 PERL 或 PHP 這樣的腳本語言,能夠很巧妙地處理轉義字符。MySQL 針對 PHP 的擴展也提供了mysql_real_escape_string() ,能夠將輸入的字符轉義爲MySQL所特有的字符。ip

if (get_magic_quotes_gpc()) 
{
  $name = stripslashes($name);
}
$name = mysql_real_escape_string($name);
mysql_query("SELECT * FROM users WHERE name='{$name}'");

LIKE 窘境

爲了解決 LIKE 困境,經常使用的轉義機制必須將 用戶所輸入的 % 和 _ 字符轉義爲字面值。使用 addcslashes() 能爲你指定一個轉義字符範圍。字符串

$sub = addcslashes(mysql_real_escape_string("%something_"), "%_");
// $sub == \%something\_
mysql_query("SELECT * FROM messages WHERE subject LIKE '{$sub}%'");
相關文章
相關標籤/搜索