SQL injection(又稱SQL注入式攻擊 或是 SQL資料隱碼攻擊),指的是利用SQL指令的輸入字串中夾帶其他的SQL指令,一般來說都是從正當的查詢指令中夾帶惡意指令
例如:非法取得資料、惡意破壞資料...等。因此在程式設計時,也必須把這個基本的安全性給考慮進去。
下面就介紹一個基本的SQL injection範例(以帳號登入為例)
首先,我們先建立一個HTML表單來傳送資料
<form action="testsql.php" method="post">
帳號:<input type="text" name="account"><br>
密碼:<input type="password" name="password"><br>
<input type="submit" value="送出">
</form>
同時也建立一個資料庫來做測試
接著就可以撰寫接收端程式
//接收帳號、密碼
$account = $_REQUEST['account'];
$pass = $_REQUEST['password'];
//密碼使用md5加密
$password = md5($pass);
//查詢有無符合帳號資料
$sql = "SELECT * FROM `test_sql` WHERE `account` LIKE '".$account."' AND `password` LIKE '".$password."'";
$res = mysql_query($sql);
$result = mysql_fetch_array($res);
if(empty($result)){
//若無符合顯示查無帳號
echo "查無此帳號<br>";
echo $sql;
echo "<br>輸入帳號".$account;
echo "<br>輸入密碼".$pass;
}else{
//若符合顯示帳號、密碼資訊
echo "帳號:".$account;
echo "<br>密碼:".$pass;
echo "<br>".$sql;
}
以此例說明:
當帳號輸入"' OR ''=''#" 或是 "' OR ''=''-- "(雙引號內字串)就可以進行非法登入(如下圖)
或是
原理:在SQL指令中 "#"和"-- "代表注釋
因此原本輸入的查詢是
"SELECT * FROM `test_sql` WHERE `account` LIKE '".$account."' AND `password` LIKE '".$password."'";
會變成account欄位等於空 或是 ''='' ,後面的密碼則被注釋掉了
"SELECT * FROM `test_sql` WHERE `account` LIKE '".$account."'' OR ''=''";
而後者條件成立,SQL指令就會開始執行(如下圖,此例取出第一筆資料)
解決這類型的非法登入的方式有幾種:
1. 使用正則表達式過濾字串;這是最搞剛卻也最安全的作法
2. 使用addslashes();這個函數會在所有的單引號前加上反斜線
下面就用addslashes()來簡單說明
//在接收的參數錢加上addslashes()
$account = addslashes($_REQUEST['account']);
$pass = addslashes($_REQUEST['password']);
再測試非法登入
輸入的資料經過轉換後,單引號的作用就失效了
這樣就能有效防範非法登入,而且對於一般人使用正當登入方法不受影響