最近學(xué)習(xí)了使用PDO技術(shù)防范SQL注入的方法,在博客里當(dāng)做一次筆記。若果有新的感悟在來(lái)添上一筆,畢竟也是剛開始學(xué)習(xí)。
一、 什么是PDO
創(chuàng)新互聯(lián)專注骨干網(wǎng)絡(luò)服務(wù)器租用十多年,服務(wù)更有保障!服務(wù)器租用,成都服務(wù)器托管 成都服務(wù)器租用,成都服務(wù)器托管,骨干網(wǎng)絡(luò)帶寬,享受低延遲,高速訪問(wèn)。靈活、實(shí)現(xiàn)低成本的共享或公網(wǎng)數(shù)據(jù)中心高速帶寬的專屬高性能服務(wù)器。
PDO全名PHP Data Object
PHP 數(shù)據(jù)對(duì)象 (PDO) 擴(kuò)展為PHP訪問(wèn)數(shù)據(jù)庫(kù)定義了一個(gè)輕量級(jí)的一致接口。
PDO 提供了一個(gè)數(shù)據(jù)訪問(wèn)抽象層,這意味著,不管使用哪種數(shù)據(jù)庫(kù),都可以用相同的函數(shù)(方法)來(lái)查詢和獲取數(shù)據(jù)。
二、如何去使用PDO防范SQL注入?
/
防范sql注入這里使用quote()方法過(guò)濾特殊字符和通過(guò)預(yù)處理的一些方式以及bindParameter()方法綁定參數(shù)來(lái)防止SQL注入
/
三、 使用quate()方法防止sql注入。
Quate()方法返回帶引號(hào)的字符串,過(guò)濾特殊字符
1、首先創(chuàng)建一個(gè)登陸界面來(lái)提交用戶名和密碼。
</!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>
2、然后創(chuàng)建后臺(tái)處理PHP文件,獲取用戶名和密碼,并在數(shù)據(jù)庫(kù)中查詢?;镜牟樵兎椒▉?lái)查詢。
<?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();
}
這個(gè)處理界面是由SQL注入的界面。
3、我們來(lái)測(cè)試一下
(1)在文本框中輸入正確的用戶名和密碼,返回正常的信息
但是當(dāng)我們進(jìn)行注入的時(shí)候,返回的信息:
(2)用戶名輸入’ or 1=1 #,密碼隨便輸入
將數(shù)據(jù)庫(kù)中的用戶信息以數(shù)組的形式全部顯示了出來(lái)。
(3)我們?cè)跀?shù)據(jù)庫(kù)中執(zhí)行這串查詢語(yǔ)句
可以看到,數(shù)據(jù)庫(kù)照常顯示,這也是sql注入一個(gè)很大的危害。
4、接下來(lái)我們通過(guò)quote()方法來(lái)防止SQL注入
通過(guò)以下代碼,將new的對(duì)象$pdo通過(guò)調(diào)用quote()方法來(lái)重新返回用戶輸入的字符串,然后在通過(guò)查詢語(yǔ)句,去查詢數(shù)據(jù)庫(kù)中的數(shù)據(jù)。
<?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();
}
5、我們來(lái)使用同樣的方法來(lái)測(cè)試一下能不能防范sql注入呢?
(1)正確用戶名和正確密碼驗(yàn)證:
(2)正確用戶名和錯(cuò)誤密碼訪問(wèn)
查詢不到數(shù)據(jù)
(3)使用sql注入:
查詢失敗,我們可以清楚的看到我們輸入的引號(hào)在前面自動(dòng)的加上了‘\’,將引號(hào)給轉(zhuǎn)義,失去了原來(lái)的作用。
(4)同時(shí)我們?cè)跀?shù)據(jù)庫(kù)中執(zhí)行一下這個(gè)語(yǔ)句。
查詢出錯(cuò)。所以quote()方法能夠有效的防止sql注入
四、 使用預(yù)處理語(yǔ)句防止SQL注入
預(yù)處理語(yǔ)句中占位符形式來(lái)防止SQL注入。占位符有兩種形式,一種是通過(guò)命名參數(shù),另一種是通過(guò)問(wèn)好占位符的形式
1、通過(guò)命名參數(shù)防止注入
(1)首先在原來(lái)基礎(chǔ)的源碼上改正查詢語(yǔ)句。改為:
Select * from where name=:username and password=:password
整個(gè)源碼:
<?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):命名用戶名參數(shù):username密碼:password。
b):通過(guò)調(diào)用rowCount()方法,查看返回受sql語(yǔ)句影響的行數(shù),返回0語(yǔ)句執(zhí)行失敗,大于等于1,語(yǔ)句執(zhí)行成功。
測(cè)試:
(1)正常訪問(wèn):用戶名zhangsan,密碼:123
(2)錯(cuò)誤密碼訪問(wèn):
(3)Sql注入語(yǔ)句訪問(wèn):
防止注入失敗
2、通過(guò)問(wèn)號(hào)(?)占位符防止注入
(1)修改sql查詢語(yǔ)句:
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();
}
?>
解釋:通過(guò)execute()方法直接傳遞數(shù)組array($username,$password)給sql語(yǔ)句查詢。
測(cè)試:
(1)正常訪問(wèn):用戶名:lisi,密碼:abc
(2)錯(cuò)誤用戶名或密碼訪問(wèn)
(3)Sql注入:
注入失敗
五、 通過(guò)bindParam()方法綁定參數(shù)防御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';
$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)關(guān)鍵代碼:
$stmt->bindParam(":username",$username,PDO::PARAM_STR);
$stmt->bindParam(":password",$password,PDO::PARAM_STR);
解釋:
a)::username和:password為命名參數(shù)
b):$username;$password為獲取的變量,即用戶名和密碼。
c):PDO::PARAM_STR,表示參數(shù)變量的值一定要為字符串,即綁定參數(shù)類型為字符串。在bindparam()方法中,默認(rèn)綁定的參數(shù)類型就是字符串。當(dāng)你要接受×××的時(shí)候可以綁定參數(shù)為PDO::PARAM_INT.
測(cè)試:
(1)正常訪問(wèn)測(cè)試:
(2)測(cè)試sql注入:
當(dāng)做是一個(gè)筆記吧還有很多的知識(shí)點(diǎn)沒(méi)有寫出來(lái),以后再慢慢補(bǔ)充吧?。?!
分享名稱:記錄一下學(xué)習(xí)PDO技術(shù)防范SQL注入的方法
瀏覽地址:http://jinyejixie.com/article4/gpehie.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站、Google、搜索引擎優(yōu)化、App設(shè)計(jì)、網(wǎng)站排名、全網(wǎng)營(yíng)銷推廣
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)