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版
Oct 09 PHP
mysql_fetch_assoc和mysql_fetch_row的功能加起来就是mysql_fetch_array
Jan 15 PHP
个人站长制做网页常用的php代码
Mar 03 PHP
IIS6的PHP最佳配置方法
Mar 19 PHP
php,ajax实现分页
Mar 27 PHP
php smarty的预保留变量总结
Dec 04 PHP
关于php curl获取301或302转向的网址问题的解决方法
Jun 02 PHP
windows中为php安装mongodb与memcache
Jan 06 PHP
了解PHP的返回引用和局部静态变量
Jun 04 PHP
twig模板获取全局变量的方法
Feb 05 PHP
yii2中LinkPager增加总页数和总记录数的实例
Aug 28 PHP
PHP中strval()函数实例用法
Jun 07 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批量生成图片缩略图的方法
2015/06/18 PHP
mysql_escape_string()函数用法分析
2016/04/25 PHP
php大小写转换函数(strtolower、strtoupper)用法介绍
2017/11/17 PHP
PHP getNamespaces()函数讲解
2019/02/03 PHP
Laravel重定向,a链接跳转,控制器跳转示例
2019/10/22 PHP
PHP获取当前时间不准确问题解决方案
2020/08/14 PHP
javascript循环变量注册dom事件 之强大的闭包
2010/09/08 Javascript
jQuery EasyUI API 中文文档 - TimeSpinner时间微调器
2011/10/23 Javascript
分享一道笔试题[有n个直线最多可以把一个平面分成多少个部分]
2012/10/12 Javascript
使用jquery hover事件实现表格的隔行换色功能示例
2013/09/03 Javascript
jQuery自定义数值抽奖活动代码
2016/06/11 Javascript
Bootstrap面板学习使用
2017/02/09 Javascript
JavaScript中的toString()和toLocaleString()方法的区别
2017/02/15 Javascript
微信小程序 数据遍历的实现
2017/04/05 Javascript
基于webpack.config.js 参数详解
2018/03/20 Javascript
jQuery实现轮播图源码
2019/10/23 jQuery
JS+css3实现幻灯片轮播图
2020/08/14 Javascript
javascript实现贪吃蛇游戏(娱乐版)
2020/08/17 Javascript
[43:41]OG vs Newbee 2019国际邀请赛淘汰赛 胜者组 BO3 第一场 8.21.mp4
2020/07/19 DOTA
Python中input和raw_input的一点区别
2014/10/21 Python
利用ctypes提高Python的执行速度
2016/09/09 Python
利用Python为iOS10生成图标和截屏
2016/09/24 Python
在Python中使用AOP实现Redis缓存示例
2017/07/11 Python
Python实现的HMacMD5加密算法示例
2018/04/03 Python
记录Python脚本的运行日志的方法
2019/06/05 Python
python删除列表元素的三种方法(remove,pop,del)
2019/07/22 Python
Pyecharts绘制全球流向图的示例代码
2020/01/08 Python
关于Tensorflow使用CPU报错的解决方式
2020/02/05 Python
Belvilla德国:在线预订度假屋
2018/04/10 全球购物
到底Java是如何传递参数的?是by value或by reference?
2012/07/13 面试题
2014年五一活动策划方案
2014/03/15 职场文书
演讲主持词
2014/03/18 职场文书
护理专业毕业生自我鉴定总结
2014/03/24 职场文书
民事诉讼授权委托书范文
2014/08/02 职场文书
奖励申请报告范文
2015/05/15 职场文书
SpringDataJPA实体类关系映射配置方式
2021/12/06 Java/Android