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查看session内容的函数
Aug 27 PHP
php 验证码实例代码
Jun 01 PHP
apache+php+mysql安装配置方法小结
Aug 01 PHP
PHP删除数组中的特定元素的代码
Jun 28 PHP
PHP运行SVN命令显示某用户的文件更新记录的代码
Jan 03 PHP
PHP中把对象转换为关联数组代码分享
Apr 09 PHP
php源码分析之DZX1.5随机数函数random用法
Jun 17 PHP
PHP实现简易blog的制作
Oct 24 PHP
PHP解耦的三重境界(浅谈服务容器)
Mar 13 PHP
thinkPHP框架可添加js事件的分页类customPage.class.php完整实例
Mar 16 PHP
关于laravel模板中生成URL的几种模式总结
Oct 18 PHP
laravel框架邮箱认证实现方法详解
Nov 22 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实现WEB动态网页静态
2006/10/09 PHP
PHP 反射机制实现动态代理的代码
2008/10/22 PHP
PHP json格式和js json格式 js跨域调用实现代码
2012/09/08 PHP
php采集内容中带有图片地址的远程图片并保存的方法
2015/01/03 PHP
php链表用法实例分析
2015/07/09 PHP
学习php设计模式 php实现单例模式(singleton)
2015/12/07 PHP
Laravel框架实现多个视图共享相同数据的方法详解
2019/07/09 PHP
JavaScript 监听textarea中按键事件
2009/10/08 Javascript
js 无提示关闭浏览器页面的代码
2010/03/09 Javascript
IE浏览器IFrame对象内存不释放问题解决方法
2014/08/22 Javascript
JavaScript Window浏览器对象模型方法与属性汇总
2015/04/20 Javascript
js判断手机号运营商的方法
2015/10/23 Javascript
JavaScript高级程序设计(第三版)学习笔记1~5章
2016/03/11 Javascript
基于MVC+EasyUI的web开发框架之使用云打印控件C-Lodop打印页面或套打报关运单信息
2016/08/29 Javascript
JavaScript 实现的checkbox经典实例分享
2016/10/16 Javascript
js判断输入框不能为空格或null值的实现方法
2018/03/02 Javascript
jQuery 操作 HTML 元素和属性的方法
2018/11/12 jQuery
JS数组扁平化(flat)方法总结详解
2019/06/24 Javascript
JavaScript中while循环的基础使用教程
2020/08/11 Javascript
使用python获取CPU和内存信息的思路与实现(linux系统)
2014/01/03 Python
启动targetcli时遇到错误解决办法
2017/10/26 Python
Python3中的json模块使用详解
2018/05/05 Python
基于DataFrame筛选数据与loc的用法详解
2018/05/18 Python
python 中Arduino串口传输数据到电脑并保存至excel表格
2019/10/14 Python
python 并发下载器实现方法示例
2019/11/22 Python
Python生成器传参数及返回值原理解析
2020/07/22 Python
Python importlib模块重载使用方法详解
2020/10/13 Python
使用HTML5的Notification API制作web通知的教程
2015/05/08 HTML / CSS
详解如何将 Canvas 绘制过程转为视频
2021/01/25 HTML / CSS
介绍一下Linux文件的记录形式
2012/04/18 面试题
swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上
2013/07/06 面试题
UNIX命令速查表
2012/03/10 面试题
初中学校对照检查材料
2014/08/19 职场文书
我是一名护士演讲稿
2014/08/28 职场文书
小学校长个人总结
2015/03/03 职场文书
学习雷锋精神倡议书
2015/04/27 职场文书