這是因為用戶可以輸入類似VALUE“); DROP TABLE表; - ,使查詢變成: 復制代碼 代碼如下: INSERT INTO table (column) VALUES('VALUE'); DROP TABLE table;'
我們應該怎么防止這種情況呢?請看下面 使用預備義語句和參數化查詢。對于帶有任何參數的sql語句都會被發送到數據庫服務器,并被解析!對于攻擊者想要惡意注入sql是不可能的! 實現這一目標基本上有兩種選擇: 1.使用PDO(PHP Data Objects ): 復制代碼 代碼如下: $stmt = $pdo- prepare('SELECT * FROM employees WHERE name = :name'); $stmt- execute(array(':name' = $name)); foreach ($stmt as $row) { // do something with $row }
2.使用mysqli: 復制代碼 代碼如下: $stmt = $dbConnection- prepare('SELECT * FROM employees WHERE name = ?'); $stmt- bind_param('s', $name); $stmt- execute(); $result = $stmt- get_result(); while ($row = $result- fetch_assoc()) { // do something with $row }
這里最重要的是,該參數值是和預編譯的語句結合的,而不是和一個SQL字符串.SQL注入的工作原理是通過欺騙手段創建的SQL腳本包括惡意字符串發送到數據庫.因此,通過發送實際的分開的sql參數,你會降低風險.使用準備好的語句時,你發送的任何參數,將只被視為字符串(雖然數據庫引擎可能會做一些參數的優化,當然最終可能會為數字).在上面的例子中,如果變量$name包含'sarah';DELETE * FROM employees,結果只會是一個搜索的字符串"'sarah';DELETE * FROM employees",你不會得到一個空表。