標籤:
長期以來,web的安全性存在著巨大的爭議與挑戰。其中,sql注入就是一種常見的一種攻擊方法,開發人員普遍的做法就是不停的過濾,轉義參數,可是我們php大法天生弱類型的機制,總是讓駭客有機可乘,繞過防禦與防禦總是在明爭暗鬥。
兄弟連(www.itxdl.cn)PHP大牛說過一句話,在一個程式中,60%的代碼都應該是在進行各種防禦。
其實,現在來看,防禦sql注入其實並不需要進行各種參數過濾,以下將開啟乾貨模式!
PHP5.x開始引入了一種新的mysql操作方式-----mysqli,在php中也有一項相應的操作方式叫做PHP預先處理。採用物件導向的方式來進行參數化綁定操作,由於對資料庫操作的模式驅動不同,因此可以非常有效防禦sql注入。
首先,我們先來看一段代碼例子
php代碼:
<!--?php
$root = "root";
$pwd = "root";
$host = "localhost";
$database = "database";
$conn = new mysqli($host,$root,$pwd,$database);//物件導向的方式執行個體化一個對象
$keywords = $_GET[‘keywords‘];
$search_sql = "select content from mykey where title = ? ";//其中的?是一個預留位置
$search_action = $conn --->prepare($search_sql);//進行預先處理操作
$search_action ->bind_param("s",$keywords);//綁定參數,第一個參數表示為上面預先處理的的預留位置的數量和每一個參數的資料類型,s為字串,i為整形,d為雙精確度小數,有幾個參數,就寫幾個s或d或i,比如說iiii,ssss,sidi這樣的。然後後面就是有幾個參數就寫幾個要綁定的變數,比如bind_param(‘sss‘,$username,$password,$code);
$search_action ->bind_result($content);//將結果綁定在相對應的變數上,比如你select了username,password,你就可以寫bind_result($usernmae,$password);
$search_action ->execute();//執行sql操作
while($search_action ->fetch()){
echo $content.‘<br>‘;
}
$search_action ->free_result();//釋放記憶體
$search_action ->close();//結束這個執行個體化
?>
上面是php預先處理中一個非常簡單的例子,它內建的其他函數能很方便我們的開發速度,那麼看到這裡,很多人可能還是不明白,有人可能想問,你這個綁定參數是不是還是在拼湊sql語句?如果是拼湊語句,那還不是會產生注入嗎?
這就要從他的操作原理來解釋了,其實它在prepare操作中,就已經在資料庫中,執行了語句,以後的綁定參數和執行,只不過是再傳遞資料進去而已,所以根本不會和sql語句拼接,也就自然不會將危險代碼執行。因此,在這種模式下sql注入就能很有效被防禦了。
在php預先處理的類中有很多很好用的操作,具體的兄弟連將會在以後的文章中為大家總結一些常用的php預先處理的開發語句。
PHP之防禦sql注入攻擊的方式