zoukankan      html  css  js  c++  java
  • [转载]PDO防注入原理分析以及使用PDO的注意事项

    本文全部内容转载自月影无痕的博客http://zhangxugg-163-com.iteye.com/blog/1835721#bc2346092,感谢作者的分享

    合理正确使用PDO,可以基本上防止SQL注入的产生,本文主要回答以下两个问题:

    a、为什么要使用PDO而不是mysql_connect?

    b、为何PDO能防注入?

    c、使用PDO防注入的时候应该特别注意什么?

    一、为何要优先使用PDO?

    提高相同SQL模板查询性能

    阻止SQL注入

    二、为何PDO能防SQL注入?

    为了彻底搞清楚php与mysql server通讯的细节,作者特别使用了wireshark抓包进行研究之。

    78ca895f-3dcf-39f3-a452-cb347a4807d1

    其实,这与我们平时使用mysql_real_escape_string将字符串进行转义,再拼接成SQL语句没有差别(只是由PDO本地驱动完成转义的),显然这种情况下还是有可能造成SQL注入的,也就是说在php本地调用pdo prepare中的mysql_real_escape_string来操作query,使用的是本地单字节字符集,而我们传递多字节编码的变量时,有可能还是会造成SQL注入漏洞(php 5.3.6以前版本的问题之一,这也就解释了为何在使用PDO时,建议升级到php 5.3.6+,并在DSN字符串中指定charset的原因。

    而正确的转义应该是给mysql Server指定字符集,并将变量发送给MySQL Server完成根据字符转义。

    那么,如何才能禁止PHP本地转义而交由MySQL Server转义呢?

    PDO有一项参数,名为PDO::ATTR_EMULATE_PREPARES ,表示是否使用PHP本地模拟prepare,此项参数默认值未知。而且根据我们刚刚抓包分析结果来看,php 5.3.6+默认还是使用本地变量转,拼接成SQL发送给MySQL Server的,我们将这项值设置为false。

    4b73404b-3cc7-37c7-8679-5200e7dc872e

    1853a6e4-6e77-3297-921f-19132a5df698

    可见这次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+, 请在在PDO的DSN中指定charset属性

    DSN中指定charset的作用是什么? 只是告诉PDO, 本地驱动转义时使用指定的字符集(并不是设定mysql server通信字符集),设置mysql server通信字符集,还得使用set names <charset>指令。

    2、如果使用了PHP 5.3.6及以前版本,设置PDO::ATTR_EMULATE_PREPARES参数为false(即由MySQL进行变量处理);因Yii框架默认并未设置ATTR_EMULATE_PREPARES的值,请在数据库配置文件中指定emulatePrepare的值为false。

  • 相关阅读:
    QAU 18校赛 J题 天平(01背包 判断能否装满)
    滚动数组
    Leapin' Lizards HDU
    Sabotage UVA
    Food HDU
    两个Button 加通一个手势,那么 第一个的就失效了,
    终于把聊天记录保存到数据库当中去了,
    添加好友,
    XEP 0055 (Jabber search) with iphone SDK
    手机ip,
  • 原文地址:https://www.cnblogs.com/zhrea/p/3932583.html
Copyright © 2011-2022 走看看