【问题标题】:Why is using a mysql prepared statement more secure than using the common escape functions?为什么使用 mysql 准备好的语句比使用常见的转义函数更安全?
【发布时间】:2010-10-18 11:14:29
【问题描述】:

另一个问题中有一条评论如下:

“当涉及到数据库查询时, 总是尝试使用准备好的 参数化查询。 mysqli 和 PDO 库支持这一点。这是 比使用转义更安全 功能如 mysql_real_escape_string。”

Source

那么,我想问的是:为什么准备好的参数化查询更安全?

【问题讨论】:

    标签: php mysql security sql-injection prepared-statement


    【解决方案1】:

    我认为这里的人们缺少的重要一点是,使用支持参数化查询的数据库,无需担心“转义”。数据库引擎不会将绑定的变量组合到 SQL 语句中,然后解析整个事情;绑定的变量是独立的,永远不会被解析为通用 SQL 语句。

    这就是安全性和速度的来源。数据库引擎知道占位符仅包含数据,因此它永远不会被解析为完整的 SQL 语句。当您准备一个语句然后多次执行它时,速度就会提高;将多条记录插入同一个表的规范示例。这种情况下,数据库引擎只需要解析、优化等一次。

    现在,一个问题是数据库抽象库。他们有时会通过将绑定变量插入到带有适当转义的 SQL 语句中来伪造它。不过,这比自己做要好。

    【讨论】:

    • 所以速度更快但安全性相同?我的意思是你不能比完全安全更安全。我还想要一些速度理论的证据。
    【解决方案2】:

    首先,您将危险字符的转义留给数据库,这比您人类安全得多。

    ...它不会忘记逃跑,也不会错过任何可用于注入恶意 SQL 的特殊字符。更不用说,您可能会在启动时获得性能提升!

    【讨论】:

    • 但是数据库如何知道危险和我真正想要它做的事情之间的区别?
    • 它知道哪些字符是邪恶的,所以它应该在 MySQL 中的邪恶字符之前添加转义字符“\”。这仍然会按原样执行查询,但不会尊重绑定中出现的任何特殊字符。
    • 还要注意,您单独指定“绑定”(未在查询中连接),只需在查询中将占位符插入到它们应该出现的位置。数据库(我想,也许是 PDO 做到了?)然后在绑定中转义字符。
    • 我现在明白了。非常感谢您的帮助:P
    【解决方案3】:

    我对安全性不是很精通,但这里有一个解释,希望对您有所帮助:

    假设您有这样的声明:

    从 mydb 中选择 [整数]

    假装当你准备它时,该语句在我们想象的 sql 实现中被编译成字节。

               01                  00 00                  23
    Opcode for select          Prepared bytes      number of "mydb"
                              for your integer
    

    现在,当您执行时,您会将数字插入为准备好的语句保留的空间中。

    如果你只是使用转义,你可能会在其中插入尽可能多的乱码,并可能导致内存溢出,或者一些他们忘记转义的奇怪 sql 命令。

    【讨论】:

      【解决方案4】:

      因为使用准备好的语句,您不能忘记转义内容。所以没有办法引入不安全感。

      如果您记得每次调用 mysql_query 时都使用 mysql_real_escape_string,则 mysql_real_escape_string 与准备好的语句一样安全,但很容易忘记。

      【讨论】:

        【解决方案5】:

        准备好的语句解决了fundamental problem of application security 单纯的数据清理无法解决的问题:它们导致数据和指令完全分离。当两者混淆时,结果就是不安全。 SQL 注入和缓冲区溢出都是如此。

        (还有其他不安全的方法。)

        【讨论】:

          【解决方案6】:

          最好的情况,可能不是,但至少同样安全;为什么要冒险?

          【讨论】:

            【解决方案7】:

            由于此漏洞http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string,该函数不安全。这就是为什么首选准备好的语句并且它也可以提高性能的原因。

            【讨论】:

            • 我相信,如果我正确阅读了链接的博客,他的问题是 addlashes 不安全,而不是 mysql_real_escape_string。他最后说,后者是一个有效的选择,如果人们记得这样做,但人们往往会忘记调用它。使用准备好的语句有助于解决内存问题。
            • 这也是一个有趣的链接,它指出了 mysql_real_escape_string 的一个潜在问题,虽然很模糊:ilia.ws/archives/…
            猜你喜欢
            • 2023-03-07
            • 1970-01-01
            • 1970-01-01
            • 2011-01-13
            • 1970-01-01
            • 2015-12-08
            • 1970-01-01
            • 1970-01-01
            • 2017-09-28
            相关资源
            最近更新 更多