PHP使用PDO实现mysql防注入功能详解


Posted in PHP onDecember 20, 2019

本文实例讲述了PHP使用PDO实现mysql防注入功能。分享给大家供大家参考,具体如下:

1、什么是注入攻击

例如下例:

前端有个提交表格:

<form action="test.php" method="post">
    姓名:<input name="username" type="text">
    密码:<input name="password" type="password">
    <input type="submit" value="登陆">
  </form>

后台的处理如下:

<?php
  $username=$_POST["username"];
  $password=$_POST["password"];
  $age=$_POST["age"];
  //连接数据库,新建PDO对象
  $pdo=new PDO("mysql:host=localhost;dbname=phpdemo","root","1234");
  
  $sql="select * from login WHERE username='{$username}' AND password='{$password}' ";
  echo $sql;
  $stmt=$pdo->query($sql);
  //rowCount()方法返回结果条数或者受影响的行数
  if($stmt->rowCount()>0){ echo "登陆成功!"};

正常情况下,如果你输入姓名为小王,密码xiaowang,会登陆成功,sql语句如下:select * from login WHERE username='小王' AND password='xiaowang' 登陆成功!

但是如果你输入姓名为 ' or 1=1 #,密码随便输一个,也会登陆成功,sql语句为:select * from login WHERE username='' or 1=1 #' AND password='xiaowang' 登陆成功!

可以看到username='' or 1=1,#注释调了之后的password语句,由于 1=1恒成立,因此这条语句会返回大于1的结果集,从而使验证通过。

2、使用quote过滤特殊字符,防止注入

在sql语句前加上一行,将username变量中的‘等特殊字符过滤,可以起到防止注入的效果

//通过quote方法,返回带引号的字符串,过滤调特殊字符
$username=$pdo->quote($username);
$sql="select * from login WHERE username={$username} AND password='{$password}' ";
echo $sql;
$stmt=$pdo->query($sql);
//rowCount()方法返回结果条数或者受影响的行数
if($stmt->rowCount()>0){
  echo "登陆成功!";
};

sql语句为:select * from login WHERE username='\' or 1=1 #' AND password='xiaowang'

可以看到“'”被转义\',并且自动为变量$username加上了引号

3、通过预处理语句传递参数,防注入

//通过占位符:username,:password传递值,防止注入
$sql="select * from login WHERE username=:username AND password=:password";
$stmt=$pdo->prepare($sql);
//通过statement对象执行查询语句,并以数组的形式赋值给查询语句中的占位符
$stmt->execute(array(':username'=>$username,':password'=>$password));
echo $stmt->rowCount();

其中的占位符也可以为?

//占位符为?
$sql="select * from login WHERE username=? AND password=?";
$stmt=$pdo->prepare($sql);
//数组中参数的顺序与查询语句中问号的顺序必须相同
$stmt->execute(array($username,$password));
echo $stmt->rowCount();

4、通过bind绑定参数

bindParam()方法绑定一个变量到查询语句中的参数:  

$sql="insert login(username,password,upic,mail) values(:username,:password,:age,:mail)";
$stmt=$pdo->prepare($sql);
//第三个参数可以指定参数的类型PDO::PARAM_STR为字符串,PDO::PARAM_INT为整型数
$stmt->bindParam(":username",$username,PDO::PARAM_STR);
$stmt->bindParam(":password",$password,PDO::PARAM_STR);
$stmt->bindParam(":age",$age,PDO::PARAM_INT);
//使用bindValue()方法绑定一个定值
$stmt->bindValue(":mail",'default@qq.com');
$stmt->execute();
echo $stmt->rowCount();

使用问号做占位符:

$sql="insert login(username,password,mail) values(?,?,?)";//注意不是中文状态下的问号? 
$stmt=$pdo->prepare($sql); //按照?的顺序绑定参数值 
$stmt->bindParam(1,$username); 
$stmt->bindParam(2,$password); 
$stmt->bindValue(3,'default@qq.com'); 
$stmt->execute(); 
echo $stmt->rowCount();

使用其中bindValue()方法给第三个占位符绑定一个常量'default@qq.com',它不随变量的变化而变化。

bindColumn()方法绑定返回结果集的一列到变量:   

$sql='SELECT * FROM user';
$stmt=$pdo->prepare($sql);
$stmt->execute();
$stmt->bindColumn(2,$username);
$stmt->bindColumn(4,$email);
while($stmt->fetch(PDO::FETCH_BOUND)){
  echo '用户名:'.$username.",邮箱:".$email.'<hr/>';
}

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
一个自定义位数的php多用户计数器代码
Mar 11 PHP
通达OA公共代码 php常用检测函数
Dec 14 PHP
CodeIgniter输出中文乱码的两种解决办法
Jun 12 PHP
php简单smarty入门程序实例
Jun 11 PHP
php实现对象克隆的方法
Jun 20 PHP
php生成固定长度纯数字编码的方法
Jul 09 PHP
Linux平台PHP5.4设置FPM线程数量的方法
Nov 09 PHP
PHP使用 Imagick 扩展实现图片合成,圆角处理功能示例
Sep 09 PHP
laravel-admin 管理平台获取当前登陆用户信息的例子
Oct 08 PHP
自定义Laravel (monolog)日志位置,并增加请求ID的实现
Oct 17 PHP
Laravel5.3+框架定义API路径取消CSRF保护方法详解
Apr 06 PHP
Laravel中获取IP的真实地理位置
Apr 01 PHP
laravel框架数据库操作、查询构建器、Eloquent ORM操作实例分析
Dec 20 #PHP
PHP+fiddler抓包采集微信文章阅读数点赞数的思路详解
Dec 20 #PHP
PHP的图像处理实例小结【文字水印、图片水印、压缩图像等】
Dec 20 #PHP
Laravel框架处理用户的请求操作详解
Dec 20 #PHP
PHP上传图片到数据库并显示的实例代码
Dec 20 #PHP
ThinkPHP类似AOP思想的参数验证的实现方法
Dec 18 #PHP
Laravel jwt 多表(多用户端)验证隔离的实现
Dec 18 #PHP
You might like
php 高性能书写
2010/12/11 PHP
PHP中获取变量的变量名的一段代码的bug分析
2011/07/07 PHP
基于jquery的给文章加入关键字链接
2010/10/26 Javascript
THREE.JS入门教程(3)着色器-下
2013/01/24 Javascript
js网页中的(运行代码)功能实现思路
2013/02/04 Javascript
jquery 跳到顶部和底部动画2句代码简单实现
2013/07/18 Javascript
动态加载dtree.js树treeview(示例代码)
2013/12/17 Javascript
JS的参数传递示例介绍
2014/02/08 Javascript
JavaScript中具名函数的多种调用方式总结
2014/11/08 Javascript
javascript实现图片上传前台页面
2015/08/18 Javascript
BootStrap.css 在手机端滑动时右侧出现空白的原因及解决办法
2016/06/07 Javascript
AngularJS控制器之间的数据共享及通信详解
2016/08/01 Javascript
AngularJs自定义服务之实现签名和加密
2016/08/02 Javascript
基于Vuejs实现购物车功能
2016/08/02 Javascript
js中遍历Map对象的简单实例
2016/08/08 Javascript
深入理解React中es6创建组件this的方法
2016/08/29 Javascript
javascript实现文字无缝滚动
2016/12/27 Javascript
详解angular中的作用域及继承
2017/05/31 Javascript
使用vue-resource进行数据交互的实例
2017/09/02 Javascript
vue如何判断dom的class
2018/04/26 Javascript
关于vue.js中实现方法内某些代码延时执行
2019/11/14 Javascript
vue实现拖拽效果
2019/12/23 Javascript
JavaScript实现简单计算器
2020/03/19 Javascript
pytorch1.0中torch.nn.Conv2d用法详解
2020/01/10 Python
Python 剪绳子的多种思路实现(动态规划和贪心)
2020/02/24 Python
python爬虫爬取淘宝商品比价(附淘宝反爬虫机制解决小办法)
2020/12/03 Python
台湾菁英交友:结识黄金单身的台湾人
2018/01/22 全球购物
美国儿童服装、家具和玩具精品店:Maisonette
2019/11/24 全球购物
捷克家具销售网站:SCONTO Nábytek
2020/01/02 全球购物
优秀幼教自荐信
2014/02/03 职场文书
教师群众路线心得体会
2014/11/04 职场文书
物业工程部经理岗位职责
2015/04/09 职场文书
致男子1500米运动员的广播稿
2019/11/08 职场文书
python迷宫问题深度优先遍历实例
2021/06/20 Python
Python Django获取URL中的数据详解
2021/11/01 Python
索尼ICF-36收音机评测
2022/04/30 无线电