转:php防止sql注入的一点心得
转:http://blog.csdn.net/sky_zhe/article/details/9702489
转:http://zhangxugg-163-com.iteye.com/blog/1835721
如何才能禁止PHP本地转义而交由MySQL Server转义呢?
PDO有一项参数,名为PDO::ATTR_EMULATE_PREPARES ,表示是否使用PHP本地模拟prepare,此项参数默认值未知。而且根据我们刚刚抓包分析结果来看,php 5.3.6+默认还是使用本地变量转,拼接成SQL发送给MySQL Server的,我们将这项值设置为false, 试试效果,如以下代码:
<?php
$pdo = new PDO("mysql:host=192.168.0.1;dbname=test;","root");
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$st = $pdo->prepare("select * from info where id =? and name = ?");
$id = 21;
$name = 'zhangsan';
$st->bindParam(1,$id);
$st->bindParam(2,$name);
$st->execute();
$st->fetchAll();
?>
红色行是我们刚加入的内容,运行以下程序,使用wireshark抓包分析,得出的结果如下:

看到了吗?这就是神奇之处,可见这次PHP是将SQL模板和变量是分两次发送给MySQL的,由MySQL完成变量的转义处理,既然变量和SQL模板是分两次发送的,那么就不存在SQL注入的问题了,但需要在DSN中指定charset属性,如:$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'root');如此,即可从根本上杜绝SQL注入的问题。
使用PDO的注意事项
1. php升级到5.3.6+,生产环境强烈建议升级到php 5.3.9+ php 5.4+,php 5.3.8存在致命的hash碰撞漏洞。
2. 若使用php 5.3.6+, 请在在PDO的DSN中指定charset属性
3. 如果使用了PHP 5.3.6及以前版本,设置PDO::ATTR_EMULATE_PREPARES参数为false(即由MySQL进行变量处理).
php 5.3.6以上版本已经处理了这个问题,无论是使用本地模拟prepare还是调用mysql server的prepare均可。在DSN中指定charset是无效的,同时set names <charset>的执行是必不可少的。
4. 如果使用了PHP 5.3.6及以前版本, 因Yii框架默认并未设置ATTR_EMULATE_PREPARES的值,请在数据库配置文件中指定emulatePrepare的值为false。那么,有个问题,如果在DSN中指定了charset, 是否还需要执行set names <charset>呢?是的,不能省。set names <charset>其实有两个作用:
A. 告诉mysql server, 客户端(PHP程序)提交给它的编码是什么
B. 告诉mysql server, 客户端需要的结果的编码是什么
也就是说,如果数据表使用gbk字符集,而PHP程序使用UTF-8编码,我们在执行查询前运行set names utf8, 告诉mysql server正确编码即可,无须在程序中编码转换。这样我们以utf-8编码提交查询到mysql server, 得到的结果也会是utf-8编码。省却了程序中的转换编码问题,不要有疑问,这样做不会产生乱码。那么在DSN中指定charset的作用是什么? 只是告诉PDO, 本地驱动转义时使用指定的字符集(并不是设定mysql server通信字符集)。
针对php 5.3.6以前版本,以下代码仍然可能造成SQL注入问题:
$pdo->query('SET NAMES GBK');
$var = chr(0xbf) . chr(0x27) . " OR 1=1 /*";
$query = "SELECT * FROM info WHERE name = ?";
$stmt = $pdo->prepare($query);
$stmt->execute(array($var));
MySQL在5.5.3之后增加了这个utf8mb4的编码,mb4就是most bytes 4的意思,专门用来兼容四字节的unicode。好在utf8mb4是utf8的超集,除了将编码改为utf8mb4外不需要做其他转换。当然,为了节省空间,一般情况下使用utf8也就够了。
注意当使用PDO访问MySQL数据库真正的预备义语句并不是默认使用的(<=php5.3.6)!为了解决这个问题,你必须禁用仿真准备好的语句。使用PDO创建连接的例子如下:
复制代码 代码如下:
$dbConnection = new PDO('mysql:dbname=dbtest;host=127.0.0.1;charset=utf8', 'user', 'pass');
$dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
在上面例子中错误模式ERRMODE不是严格必须的,但是建议添加它。当运行出错产生致命错误时,这种方法脚本不会停止。并给开发人员捕捉任何错误的机会(当抛出PDOException异常时)。setAttribute()那一行是强制性的,它告诉PDO禁用仿真预备义语句,使用真正的预备义语句。这可以确保语句和值在发送给MySQL数据库服务器前不被PHP解析(攻击者没有机会注入恶意的SQL).
转:php防止sql注入的一点心得的更多相关文章
- 转:PHP中防止SQL注入的方法
[一.在服务器端配置] 安全,PHP代码编写是一方面,PHP的配置更是非常关键. 我们php手手工安装的,php的默认配置文件在 /usr/local/apache2/conf/php.ini,我们最 ...
- SQL注入(一) - 入门篇
什么是SQL注入 可能大家还不是对SQL注入这个概念不是很清楚,简单地说,SQL注入就是攻击者通过正常的WEB页面,把自己SQL代码传入到应用程序中,从而通过执行非程序员预期的SQL代码,达到窃取数据 ...
- SQL注入攻击三部曲之入门篇
SQL注入攻击三部曲之入门篇 服务器安全管理员和攻击者的战争仿佛永远没有停止的时候,针对国内网站的ASP架构的SQL注入攻击又开始大行其道.本篇文章通过SQL注入攻击原理引出SQL注入攻击的实施方法, ...
- php防止sql注入的方法(转)
[一.在服务器端配置] 安全,PHP代码编写是一方面,PHP的配置更是非常关键. 我们php手手工安装的,php的默认配置文件在 /usr/local/apache2/conf/php.ini,我们最 ...
- sql注入一点小心得
好久没写技术博客,最近研究产品关于用户体验方面较多,加上项目突然比较多,设计原型.跟进开发.设计师等工作着实没时间写博客. 接下来技术上主要php深入学习和mysql优化.这两天看了关于sql注入方面 ...
- sql注入学习心得与sqlmap使用心得
做题是最好的老师 首先先来分享一下我用来练手的题目,实验吧中的简单的sql注入1,2,3 不得不说,sql注入真是一个神奇的东西,至少我以前看起来一点头绪都没有的题目能入手了 首先是简单的sql注入3 ...
- sql注入中关于--+的一点探索
在sql-labs游戏中,经常使用--+放在最后注释多余部分,而mysql中的注释符为#和-- 却不能直接使用,以前没学过mysql,一直不理解,也不知道+号的作用,今天有时间特地探索了一下,算是搞明 ...
- sql注入总结(一)--2018自我整理
SQL注入总结 前言: 本文和之后的总结都是进行总结,详细实现过程细节可能不会写出来~ 所有sql语句均是mysql数据库的,其他数据库可能有些函数不同,但是方法大致相同 0x00 SQL注入原理: ...
- Web安全学习笔记 SQL注入下
Web安全学习笔记 SQL注入下 繁枝插云欣 --ICML8 SQL注入小技巧 CheatSheet 预编译 参考文章 一点心得 一.SQL注入小技巧 1. 宽字节注入 一般程序员用gbk编码做开发的 ...
随机推荐
- 使用git拉取github上的项目
一. 安装Git 去Git官网,下载安装包,一路点next,默认安装. 安装之后,在空白处右键,菜单显示有 Git GUI Here 和 Git Bash Here ,表示Git安装成功. 二. 配置 ...
- 关于NuGet
一.NuGet是什么? NuGet是Microsoft开发平台的程序集包管理器,它由客户端工具和服务端站点组成,客户端工具提供给用户管理和安装/卸载软件程序包,以及打包和发布程序包到NuGet服务端站 ...
- 数组A - 财务管理
Larry graduated this year and finally has a job. He's making a lot of money, but somehow never seems ...
- [NOIP2003]栈 题解(卡特兰数)
[NOIP2003]栈 Description 宁宁考虑的是这样一个问题:一个操作数序列,从1,2,一直到n(图示为1到3的情况),栈A的深度大于n. 现在可以进行两种操作: 1.将一个数,从操作数序 ...
- 【leetcode 简单】第三十六题 最小栈
设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈. push(x) -- 将元素 x 推入栈中. pop() -- 删除栈顶的元素. top() -- 获取栈顶元素. ...
- 【leetcode 简单】第四题 罗马数字转整数
罗马数字包含以下七种字符:I, V, X, L,C,D 和 M. 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如, 罗马数字 2 写做 II ,即为两个并列 ...
- Django之利用ajax实现图片预览
利用ajax实现图片预览的步骤为: 程序实现的方法为: 方法一: upload.html <!DOCTYPE html> <html lang="en"> ...
- WordPress浏览数插件的安装使用
插件安装很容易,但是和大多插件都一样,安装后需要调用代码才能显示,我安装后,也调用了.但是就是不显示,后来才发现,我从其他地方复制过来的代码,函数是中文的单引号,这样致使函数失效,注意代码中参数的引号 ...
- 深入理解Spring系列之四:BeanDefinition装载前奏曲
转载 https://mp.weixin.qq.com/s?__biz=MzI0NjUxNTY5Nw==&mid=2247483835&idx=1&sn=276911368d4 ...
- netif_start_queue/netif_wake_queue/netif_stop_queue
在网卡驱动中,内核为发送数据包的流量控制提供了几个主要的函数,用来在驱动程序和内核之间传递流控信息. 主要有4个: 1]netif_start_queue 启动接口传输队列 2]netif_wake ...