V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
byc8888
V2EX  ›  PHP

请问一下大家都是怎么防 MYSQL 注入的。菜鸟我一直纠结这个!

  •  
  •   byc8888 · 2015-01-07 18:31:44 +08:00 · 5897 次点击
    这是一个创建于 3367 天前的主题,其中的信息可能已经有所发展或是发生改变。

    首先肯定要不可信所有外部传入的参数,都得检验!
    我常用的有 addslashes mysql_escape_string

    但是这两个函数听说不是很可靠。

    想请问下大家是用什么方法!

    26 条回复    2015-01-09 15:05:21 +08:00
    cevincheung
        1
    cevincheung  
       2015-01-07 18:34:36 +08:00   ❤️ 1
    PDO prepare

    ```php
    $db = new PDO('mysql:host=ip;dbname=database;charset=utf8','root','password', array(PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION));

    $sth = $db->prepare('select field from table where field = :field');
    $sth->bindParam(':field', $_GET['field'],PDO::PARAM_STR);
    $sth->execute();
    $rows = $sth->fetchAll(2);
    print_r($rows);
    ```

    更多用法请参考
    http://cn2.php.net/manual/zh/pdo.prepare.php
    lincanbin
        2
    lincanbin  
       2015-01-07 18:38:32 +08:00
    Pdo参数绑定,这是一个封装好的,支持where in的Pdo类
    https://github.com/lincanbin/PHP-PDO-MySQL-Class
    byc8888
        3
    byc8888  
    OP
       2015-01-07 18:39:35 +08:00
    @cevincheung
    @lincanbin
    谢谢您的指点!
    shiny
        4
    shiny  
       2015-01-07 18:41:10 +08:00
    mysql_real_escape_string or PDO
    xoxo
        5
    xoxo  
       2015-01-07 18:42:17 +08:00
    POD是最好的方式
    byc8888
        6
    byc8888  
    OP
       2015-01-07 18:45:38 +08:00
    @shiny
    谢谢 :)
    byc8888
        7
    byc8888  
    OP
       2015-01-07 18:46:12 +08:00
    @xoxo
    谢谢:) 我去看看!
    Kilerd
        8
    Kilerd  
       2015-01-07 18:46:48 +08:00
    @cevincheung PDO 与mysqli 孰优孰劣? 原因?
    lincanbin
        9
    lincanbin  
       2015-01-07 18:52:32 +08:00
    @Kilerd 实际性能上mysqli要稍微好一些,但是PDO是通用接口,可以在尽量少修改的情况下切换到另一种数据库,开源项目比较推荐用这个,并且Pdo支持HashTable形式的参数绑定,适合绑定大量数据的场景。
    az
        10
    az  
       2015-01-07 18:53:28 +08:00
    用框架,或者妹抖
    Kilerd
        11
    Kilerd  
       2015-01-07 18:55:57 +08:00
    @lincanbin 我感觉PHP下还是用mysqli好一点,毕竟PHP对mysql的支持度可以说比较好的。
    主要是自己用不惯在php下用SQLite或者mongo
    lincanbin
        12
    lincanbin  
       2015-01-07 19:02:30 +08:00   ❤️ 1
    @Kilerd Pdo与mysqli封装成类后,在使用上区别也不大,就算目前只用MySQL我还是使用Pdo,这个PHP官方现在也是比较推荐使用Pdo的。
    Pdo比mysqli额外多支持HashTable这种参数绑定方法
    $db->query("INSERT INTO fruit(id,name,color) VALUES(?,?,?)", array(null,"mango","yellow"));
    $db->query("INSERT INTO fruit(id,name,color) VALUES(:id,:name,:color)", array("color"=>"yellow","name"=>"mango","id"=>null));
    数据可以乱序,在绑定字段多的时候阅读起来也比较方便。
    yangzh
        13
    yangzh  
       2015-01-07 19:05:02 +08:00 via iPad
    @Kilerd pdo已经官方推荐做法
    Kilerd
        14
    Kilerd  
       2015-01-07 19:08:53 +08:00
    @lincanbin @yangzh 看起来不错,等下去研究研究。
    cevincheung
        15
    cevincheung  
       2015-01-07 19:19:40 +08:00
    @Kilerd

    mysqli是在普通mysql的基础上做的一次优化,预处理方式完全解决了sql注入的问题。但是唯一的不足点 就是只支持mysql数据库。当然,如果你要是不操作其他的数据库,这无疑是最好的选择。

    PDO则是连接方式兼容大部分数据库,也解决了sql注入。但是也有缺点,它只支持php5以上的版本(不过听说在未来的php6中只支持这种连接)。

    PDO统一所有数据库抽象层对象接口,mysqli只统一mysql的。简单说,PDO可以实现同样的代码对不同数据库的操作,例如你从mysql迁移到mssql,程序基本不需要改动。而mysqli简单理解未mysql的封装就好。

    在高负载的情况下,PDO开启长连接能够得到一个相对稳定的负载“值”。但是效率却不是最高的。 mysql最快。mysqli其次。只是mysql和mysqli在高并发、系统高负载的时候,其所承担的负载也是很可观的。PDO则不会。

    via: http://www.163ns.com/zixun/post/5204.html

    上面说的更改数据库不用更改代码不太现实。就拿limit来说, oracle和mssql是不支持这个语法的。mysql是 limit n,n 或者 limit n offset n。pgsql只支持 limit n offset n。所以在日常写sql的时候最好兼顾其他的sql格式。一些封装的ORM库针对不同的数据库都有自己的Adapter来区分。
    RIcter
        16
    RIcter  
       2015-01-07 19:50:07 +08:00 via iPhone
    _(:з」∠)_
    Drupal 也是 PDO,但是却也出现了 SQL Injection 呢…
    lincanbin
        17
    lincanbin  
       2015-01-07 19:53:03 +08:00
    @RIcter 看谁在用,用PDO也可以跟MySQL一样直接拼接字符串,不了解SQL注入不用参数绑定自己作死没人救得了。
    catfan
        18
    catfan  
       2015-01-07 20:08:08 +08:00
    msg7086
        19
    msg7086  
       2015-01-07 20:59:32 +08:00
    自从用了ORM以后我觉得已经很久很久没考虑过注入的问题了……
    liyandong
        20
    liyandong  
       2015-01-07 21:20:32 +08:00
    ijophy
        21
    ijophy  
       2015-01-08 01:53:02 +08:00
    PDO 预处理
    JamesRuan
        22
    JamesRuan  
       2015-01-08 02:04:32 +08:00 via Android
    转义,参数化
    Sunyanzi
        23
    Sunyanzi  
       2015-01-08 04:38:45 +08:00   ❤️ 1
    @RIcter Drupal 的那个注入漏洞其实跟 PDO 没关系 ... 分明是构装 SQL 时候的逻辑错误 ...

    对于 PDO 的 MySQL Driver 而言 ...

    正确使用 prepare / execute 和 PDO::ATTR_EMULATE_PREPARES 就是绝对安全的 ...
    vibbow
        24
    vibbow  
       2015-01-08 06:34:52 +08:00
    huigeer
        25
    huigeer  
       2015-01-08 09:18:44 +08:00
    PDO Mysqli, 检测方法 sqlmap
    flash866
        26
    flash866  
       2015-01-09 15:05:21 +08:00
    PDO预处理。但是用了预处理,就无法返回exec后的影响的行数,要返回行数的话,就必须手工转义。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5425 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 52ms · UTC 08:09 · PVG 16:09 · LAX 01:09 · JFK 04:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.