最近學習了使用PDO技術防範SQL注入的方法,在博客裏當作一次筆記。若果有新的感悟在來添上一筆,畢竟也是剛開始學習。
1、 什麼是PDOphp
PDO全名PHP Data Object PHP 數據對象 (PDO) 擴展爲PHP訪問數據庫定義了一個輕量級的一致接口。 PDO 提供了一個數據訪問抽象層,這意味着,無論使用哪一種數據庫,均可以用相同的函數(方法)來查詢和獲取數據。
2、如何去使用PDO防範SQL注入?
/
防範sql注入這裏使用quote()方法過濾特殊字符和經過預處理的一些方式以及bindParameter()方法綁定參數來防止SQL注入
/
3、 使用quate()方法防止sql注入。html
Quate()方法返回帶引號的字符串,過濾特殊字符
一、首先建立一個登錄界面來提交用戶名和密碼。mysql
</!DOCTYPE html> <html> <head> <title></title> </head> <body> <form action="doAction1.php" method="post"> <input type="text" name="username"></br> <input type="password" name="password"></br> <input type="submit" name="submit"> </form> </body> </html>
二、而後建立後臺處理PHP文件,獲取用戶名和密碼,並在數據庫中查詢。基本的查詢方法來查詢。sql
<?php header('content-type=text/html;charset=utf-8'); $username=$_POST['username']; $password=$_POST['password']; try{ $pdo=new PDO('mysql:host=localhost;dbname=pdotest','root','123'); $sql="select * from user where name=‘{$username}’ and password=‘{$password}’"; echo $sql."</br>"; $row=$pdo->query($sql); foreach ($row as $key => $value) { print_r($value); } }catch(POOException $e){ echo $e->getMessage(); }
這個處理界面是由SQL注入的界面。
三、咱們來測試一下
(1)在文本框中輸入正確的用戶名和密碼,返回正常的信息
可是當咱們進行注入的時候,返回的信息:
(2)用戶名輸入’ or 1=1 #,密碼隨便輸入
將數據庫中的用戶信息以數組的形式所有顯示了出來。
(3)咱們在數據庫中執行這串查詢語句
能夠看到,數據庫照常顯示,這也是sql注入一個很大的危害。
四、接下來咱們經過quote()方法來防止SQL注入
經過如下代碼,將new的對象$pdo經過調用quote()方法來從新返回用戶輸入的字符串,而後在經過查詢語句,去查詢數據庫中的數據。數據庫
<?php header('content-type=text/html;charset=utf-8'); $username=$_POST['username']; $password=$_POST['password']; try{ $pdo=new PDO('mysql:host=localhost;dbname=pdotest','root','123'); $username=$pdo->quote($username); $password=$pdo->quote($password); $sql="select * from user where name='{$username}' and password='{$password}'"; echo $sql."</br>"; $row=$pdo->query($sql); foreach ($row as $key => $value) { print_r($value); } }catch(POOException $e){ echo $e->getMessage(); }
五、咱們來使用一樣的方法來測試一下能不能防範sql注入呢?
(1)正確用戶名和正確密碼驗證:
(2)正確用戶名和錯誤密碼訪問
查詢不到數據
(3)使用sql注入:
查詢失敗,咱們能夠清楚的看到咱們輸入的引號在前面自動的加上了‘\’,將引號給轉義,失去了原來的做用。
(4)同時咱們在數據庫中執行一下這個語句。
查詢出錯。因此quote()方法可以有效的防止sql注入
4、 使用預處理語句防止SQL注入
預處理語句中佔位符形式來防止SQL注入。佔位符有兩種形式,一種是經過命名參數,另外一種是經過問好佔位符的形式
一、經過命名參數防止注入
(1)首先在原來基礎的源碼上改正查詢語句。改成:
Select * from where name=:username and password=:password
整個源碼:數組
<?php header('content-type:text/html;charset=utf-8'); $username=$_POST['username']; $password=$_POST['password']; try{ $pdo=new PDO('mysql:host=localhost;dbname=pdotest','root','123'); $sql='select * from user where name=:username and password=:password'; $stmt=$pdo->prepare($sql); $stmt->execute(array(":username"=>$username,":password"=>$password)); echo $stmt->rowCount(); }catch(PDOException $e){ echo $e->getMessage(); } ?>
解釋:
a):命名用戶名參數:username密碼:password。
b):經過調用rowCount()方法,查看返回受sql語句影響的行數,返回0語句執行失敗,大於等於1,語句執行成功。
測試:
(1)正常訪問:用戶名zhangsan,密碼:123
(2)錯誤密碼訪問:
(3)Sql注入語句訪問:
防止注入失敗ide
二、經過問號(?)佔位符防止注入
(1)修改sql查詢語句:
Select * from user where name=? and password=?
完整代碼:函數
<? header('content-type:text/html;charset=utf-8'); $username=$_POST['username']; $password=$_POST['password']; try{ $pdo=new PDO('mysql:host=localhost;dbname=pdotest','root','123'); $sql="select * from user where name=? and password=?"; $stmt=$pdo->prepare($sql); $stmt->execute(array($username,$password)); echo $stmt->rowCount(); }catch(PDOException $e){ echo $e->getMessage(); } ?>
解釋:經過execute()方法直接傳遞數組array($username,$password)給sql語句查詢。
測試:
(1)正常訪問:用戶名:lisi,密碼:abc
(2)錯誤用戶名或密碼訪問
(3)Sql注入:
注入失敗
5、 經過bindParam()方法綁定參數防護SQL注入。post
<?php header('content-type:text/html;charset=utf-8'); $username=$_POST['username']; $password=$_POST['password']; try{ $pdo=new PDO('mysql:host=localhost;dbname=pdotest','root','123'); $sql='select * from user where name=:username and password=:password'; $stmt=$pdo->prepare($sql); $stmt->bindParam(":username",$username,PDO::PARAM_STR); $stmt->bindParam(":password",$password,PDO::PARAM_STR); $stmt->execute(); echo $stmt->rowCount(); }catch(PDOException $e){ echo $e->getMessage(); } ?>
(1)關鍵代碼:
$stmt->bindParam(":username",$username,PDO::PARAM_STR);
$stmt->bindParam(":password",$password,PDO::PARAM_STR);學習
解釋:
a)::username和:password爲命名參數
b):$username;$password爲獲取的變量,即用戶名和密碼。
c):PDO::PARAM_STR,表示參數變量的值必定要爲字符串,即綁定參數類型爲字符串。在bindparam()方法中,默認綁定的參數類型就是字符串。當你要接受×××的時候能夠綁定參數爲PDO::PARAM_INT.
測試:
(1)正常訪問測試:
(2)測試sql注入:
當作是一個筆記吧還有不少的知識點沒有寫出來,之後再慢慢補充吧!!!