php防止SQL注入的方法分享

在php編程中,防範sql注入攻擊的簡單方法,感興趣的朋友可以參考下,可能對日常的sql注入防範有一定的幫助。就跟隨小編去了解下吧,想了解更多相關信息請 持續關注我們應屆畢業生考試網!

php防止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'";

?>

當該語句發送到MySQL後,系統就會顯示如下錯誤信息:

You have an error in your SQL syntax. Check the manual that corresponds to your

MySQL server version for the right syntax to use near 'WHERE username = ''' AND

password = 'a029d0df84eb55

不費吹灰之力,攻擊者已經知道了兩個字段名(username和password)以及他們出現在查詢中的順序。除此以外,攻擊者還知道了數據沒有正確進行過濾(程序沒有提示非法用戶名)和轉義(出現了數據庫錯誤),同時整個WHERE條件的格式也暴露了,這樣,攻擊者就可以嘗試操縱符合查詢的記錄了。

在這一點上,攻擊者有很多選擇。一是嘗試填入一個特殊的用戶名,以使查詢無論用戶名密碼是否符合,都能得到匹配:

myuser' or 'foo' = 'foo' --

假定將mypass作爲密碼,整個查詢就會變成:

複製代碼 代碼示例:

<?php

$sql = "SELECT *

FROM users

WHERE username = 'myuser' or 'foo' = 'foo' --

AND password = 'a029d0df84eb5549c641e04a9ef389e5'";

?>

幸運的是,SQL注入是很容易避免的。正如前面所提及的,你必須堅持過濾輸入和轉義輸出。

雖然兩個步驟都不能省略,但只要實現其中的一個就能消除大多數的SQL注入風險。如果你只是過濾輸入而沒有轉義輸出,你很可能會遇到數據庫錯誤(合法的數據也可能影響SQL查詢的正確格式),但這也不可靠,合法的數據還可能改變SQL語句的行爲。另一方面,如果你轉義了輸出,而沒有過濾輸入,就能保證數據不會影響SQL語句的格式,同時也防止了多種常見SQL注入攻擊的方法。