在php程式設計中,防範sql注入攻擊的簡單方法,感興趣的朋友可以參考下,可能對日常的sql注入防範有一定的幫助。
sql注入產生的原因,一般如下:
一個是沒有對輸入的資料進行過濾(過濾輸入),還有一個是沒有對傳送到資料庫的資料進行轉義(轉義輸出)。
這兩個重要的步驟缺一不可,需要同時加以特別關注以減少程式錯誤。
對於攻擊者來說,進行SQL注入攻擊需要思考和試驗,對資料庫方案進行有根有據的推理非常有必要(當然假設攻擊者看不到你的源程式和資料庫方案)。
例子, 一個簡單的登入表單:
複製程式碼 程式碼示例:
<form action="/" method="POST">
<p>Username: <input type="text" name="username" /></p>
<p>Password: <input type="password" name="password" /></p>
<p><input type="submit" value="Log In" /></p>
</form>
攻擊者會從推測驗證使用者名稱和密碼的查詢語句開始。通過檢視原始檔,他就能開始猜測你的習慣。
比如命名習慣。通常會假設你表單中的欄位名為與資料表中的欄位名相同。當然,確保它們不同未必是一個可靠的安全措施。
第一次猜測,一般會使用下面例子中的查詢:
複製程式碼 程式碼示例:
<?php
$password_hash = md5($_POST['password']);
$sql = "SELECT count(*)
FROM users
WHERE username = '{$_POST['username']}'
AND password = '$password_hash'";
?>
使用使用者密碼的MD5值原來是一個通行的做法,但現在並不是特別安全了。
最近的研究表明MD5演算法有缺陷,而且大量MD5資料庫降低了MD5反向破解的難度。
請訪問 檢視演示。
最好的保護方法:
在密碼上附加一個自定義的字串,例如:
複製程式碼 程式碼示例:
<?php
$salt = 'SHIFLETT';
$password_hash = md5($salt . md5($_POST['password'] . $salt));
?>
當然,攻擊者未必在第一次就能猜中,他們常常還需要做一些試驗。有一個比較好的試驗方式是把單引號作為使用者名錄入,原因是這樣可能會暴露一些重要資訊。有很多開發人員在Mysql語句執行出錯時會呼叫函式mysql_error()來報告錯誤。見下面的例子:
複製程式碼 程式碼示例:
<?php
mysql_query($sql) or exit(mysql_error());
?>
該方法能向攻擊者暴露重要資訊。如果攻擊者把單引號做為使用者名稱,mypass做為密碼,查詢語句就會變成:
複製程式碼 程式碼示例:
<?php
$sql = "SELECT *
FROM users
WHERE username = '''
AND password = 'a029d0df84eb5549c641e04a9ef389e5'";
?>