转: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注入的一点心得的更多相关文章

  1. 转:PHP中防止SQL注入的方法

    [一.在服务器端配置] 安全,PHP代码编写是一方面,PHP的配置更是非常关键. 我们php手手工安装的,php的默认配置文件在 /usr/local/apache2/conf/php.ini,我们最 ...

  2. SQL注入(一) - 入门篇

    什么是SQL注入 可能大家还不是对SQL注入这个概念不是很清楚,简单地说,SQL注入就是攻击者通过正常的WEB页面,把自己SQL代码传入到应用程序中,从而通过执行非程序员预期的SQL代码,达到窃取数据 ...

  3. SQL注入攻击三部曲之入门篇

    SQL注入攻击三部曲之入门篇 服务器安全管理员和攻击者的战争仿佛永远没有停止的时候,针对国内网站的ASP架构的SQL注入攻击又开始大行其道.本篇文章通过SQL注入攻击原理引出SQL注入攻击的实施方法, ...

  4. php防止sql注入的方法(转)

    [一.在服务器端配置] 安全,PHP代码编写是一方面,PHP的配置更是非常关键. 我们php手手工安装的,php的默认配置文件在 /usr/local/apache2/conf/php.ini,我们最 ...

  5. sql注入一点小心得

    好久没写技术博客,最近研究产品关于用户体验方面较多,加上项目突然比较多,设计原型.跟进开发.设计师等工作着实没时间写博客. 接下来技术上主要php深入学习和mysql优化.这两天看了关于sql注入方面 ...

  6. sql注入学习心得与sqlmap使用心得

    做题是最好的老师 首先先来分享一下我用来练手的题目,实验吧中的简单的sql注入1,2,3 不得不说,sql注入真是一个神奇的东西,至少我以前看起来一点头绪都没有的题目能入手了 首先是简单的sql注入3 ...

  7. sql注入中关于--+的一点探索

    在sql-labs游戏中,经常使用--+放在最后注释多余部分,而mysql中的注释符为#和-- 却不能直接使用,以前没学过mysql,一直不理解,也不知道+号的作用,今天有时间特地探索了一下,算是搞明 ...

  8. sql注入总结(一)--2018自我整理

    SQL注入总结 前言: 本文和之后的总结都是进行总结,详细实现过程细节可能不会写出来~ 所有sql语句均是mysql数据库的,其他数据库可能有些函数不同,但是方法大致相同 0x00 SQL注入原理: ...

  9. Web安全学习笔记 SQL注入下

    Web安全学习笔记 SQL注入下 繁枝插云欣 --ICML8 SQL注入小技巧 CheatSheet 预编译 参考文章 一点心得 一.SQL注入小技巧 1. 宽字节注入 一般程序员用gbk编码做开发的 ...

随机推荐

  1. 1.5 Scipy:高级科学计算

    sklearn实战-乳腺癌细胞数据挖掘(博主亲自录制视频教程) https://study.163.com/course/introduction.htm?courseId=1005269003&am ...

  2. BZOJ2588:LCA+主席树来实现树上两点之间第K大点权查询

    对于每个节点维护这个节点到根的权值线段树 对于每个询问(x,y),这条路径上的线段树 tree[x]+tree[y]-tree[lca(x,y)]-tree[fa[lca(x,y)]] #includ ...

  3. 千里之行始于足下,node.js 资源中文导航

    响应@jiyinyiyong 号召,cnodjs 好的资源蛮多的,的确欠缺分类,在一群FAQ中,的确很容易沉下去,根据自己对node.js的理解,做成一个资源导航,PS:如果觉得合适,希望能够合并的c ...

  4. TED_Topic2:My desperate journey with a human smuggler

    My desperate journey with a human smuggler By Barat Ali Batoor When I was a child there was a toy wh ...

  5. 【BZOJ】3036: 绿豆蛙的归宿

    [题意]给定DAG带边权连通图,保证所有点都能到达终点n,每个点等概率沿边走,求起点1到终点n的期望长度.n<=10^5. [算法]期望DP [题解]f[i]表示到终点n的期望长度. f[n]= ...

  6. Java读取大文件的高效率实现

    1.概述 本教程将演示如何用Java高效地读取大文件.这篇文章是Baeldung (http://www.baeldung.com/) 上“Java——回归基础”系列教程的一部分. 2.在内存中读取 ...

  7. LintCode题解之子树

    思路: 最简单的方法,依次遍历比较就可以了. AC代码: /** * Definition of TreeNode: * public class TreeNode { * public int va ...

  8. 手机网页的头部meta的相关配置~~

    今天使用sublime写手机端网页的时候,发现木有meta的自动生成手机网页的快捷键·~ 然后就去网上巴拉,准备存储一份~~哈哈 一.天猫 <title>天猫触屏版</title&g ...

  9. 如何关闭sublime更新提示

    前提:sublime已激活

  10. android ViewPager之OnPageChangeListener接口

    项目中在使用ViewPager的时候,一般都要在界面滑动的时候做一些事情,android中有个专门的状态回调接口OnPageChangeListener. /** * Callback interfa ...