zoukankan      html  css  js  c++  java
  • PDO防止sql注入的机制

    使用PDO訪问MySQL数据库时,真正的real prepared statements 默认情况下是不使用的。

    为了解决问题,你必须禁用 prepared statements的仿真效果。

    以下是使用PDO创建链接的样例:

    代码例如以下:
    $dbh = new PDO('mysql:dbname=dbtest;host=127.0.0.1;charset=utf8', 'user', 'pass');
    $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

    setAttribute() 这一行是强制性的。它会告诉 PDO 禁用模拟预处理语句,并使用 real parepared statements 。这能够确保SQL语句和对应的值在传递到mysqlserver之前是不会被PHP解析的(禁止了全部可能的恶意SQL注入攻击)。

    尽管你能够配置文件里设置 字符集的属性(charset=utf8),可是须要格外注意的是,老版本号的 PHP( < 5.3.6)在DSN中是忽略字符參数的。

    我们来看一段完整的代码使用实例:

    代码例如以下:
    $dbh = new PDO("mysql:host=localhost; dbname=dbtest", "user", "pass");
    $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); //禁用prepared statements的仿真效果
    $dbh->exec("set names 'utf8'");
    $sql="select * from test where name = ? and password = ?

    "; $stmt = $dbh->prepare($sql); $exeres = $stmt->execute(array($testname, $pass)); if ($exeres) { while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { print_r($row); } } $dbh = null;


    上面这段代码就能够防范sql注入。为什么呢?

    当调用 prepare() 时,查询语句已经发送给了数据库server,此时仅仅有占位符 ? 发送过去,没实用户提交的数据。当调用到 execute()时。用户提交过来的值才会传送给数据库,他们是分开传送的,两者独立的,SQL攻击者没有一点机会。

    可是我们须要注意的是下面几种情况,PDO并不能帮助你防范SQL注入

    1、你不能让占位符 ?

    取代一组值,如:

    代码例如以下:

    SELECT * FROM blog WHERE userid IN ( ? );


    2、你不能让占位符取代数据表名或列名。如:

    代码例如以下:
    SELECT * FROM blog ORDER BY ?;

    3、你不能让占位符 ? 取代不论什么其它SQL语法。如:
    代码例如以下:

    SELECT EXTRACT( ? FROM datetime_column) AS variable_datetime_element FROM blog;



  • 相关阅读:
    使用tcmalloc编译启动时宕机
    使用tcmalloc编译出现undefined reference to `sem_init'
    使用AddressSanitizer做内存分析(一)——入门篇
    VIM-美化你的标签栏
    Entity Framework Code First (六)存储过程
    Entity Framework Code First (五)Fluent API
    Entity Framework Code First (四)Fluent API
    Entity Framework Code First (三)Data Annotations
    Entity Framework Code First (二)Custom Conventions
    Entity Framework Code First (一)Conventions
  • 原文地址:https://www.cnblogs.com/blfbuaa/p/7298484.html
Copyright © 2011-2022 走看看