【问题标题】:mysqli prepared statements and mysqli_real_escape_stringmysqli 准备好的语句和 mysqli_real_escape_string
【发布时间】:2011-03-07 06:57:54
【问题描述】:

我目前正在使用 mysqli php 扩展。

传统上我使用 mysqli_real_escape_string 来转义用户输入。但是我正在考虑更改代码(希望尽可能少的步骤)以使用准备好的语句。

我想明确这一点 - 如果我使用准备好的语句来绑定我的所有变量,我可以确信 sql 注入是不可能的吗? (并且完全不用mysqli_real_escape_string?)

谢谢

【问题讨论】:

    标签: php mysqli sql-injection prepared-statement


    【解决方案1】:

    如果您正确绑定所有变量,您可以显着降低 SQL 注入的风险。如果您动态创建 SQL,仍然有可能获得 SQL 注入,例如:

    'SELECT * FROM ' . $tablename . ' WHERE id = ?'
    

    但如果你避免这样的事情,你不太可能会遇到问题。

    【讨论】:

    【解决方案2】:

    谈到安全性,如果您正确绑定或格式化变量,这两种方法之间没有区别。

    绑定更简单,因为它可以用于任何情况,而转义不能(因此,您必须转换一些变量而不是转义/引用)。

    另外,请记住,任何绑定或转义都不能使标识符安全。因此,如果您必须在查询中使用字段名称或运算符,则必须使用在脚本中硬编码的值。

    【讨论】:

      【解决方案3】:

      这是我对该主题的高级看法。

      当使用动态 SQL 字符串时,您依赖转义函数正常工作。不幸的是,情况并非总是如此,从这个(诚然旧的)示例中可以看出:

      http://dev.mysql.com/doc/refman/5.0/en/news-5-0-22.html

      一旦您的数据值被转义,SQL 字符串就必须由数据库服务器解析和编译。如果转义函数没有正确完成它的工作,或者发现了一个巧妙的新 SQL 注入攻击,服务器就有可能将数据误认为是 SQL 语句。

      如果你使用带参数的预处理语句,语句首先被解析和编译。数据值在执行时与编译语句结合。这将 SQL 逻辑与数据值分开 - 混淆两者的机会应该永远不会发生。

      所以,是的,您可以省去mysqli_real_escape_string,但我不会说使用带参数的准备好的语句使 SQL 注入成为不可能。这使得它变得更加困难,但与mysqli_real_escape_string 错误一样,我想总是有可能一个尚未发现(或新创建)的错误会使看似不可能的错误成为可能。

      【讨论】:

        猜你喜欢
        • 2010-11-12
        • 2012-12-01
        • 2011-07-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-18
        相关资源
        最近更新 更多