4

快一个。

我正在将使用 mysql 的旧 Web 应用程序迁移到 mysqli。我曾经使用我编写的自定义清理功能来防止 SQL 注入:

    function sani($text=""){
    if (!is_array($text)) { 
        $text = str_replace("<", "&lt;", $text); 
        $text = str_replace(">", "&gt;", $text); 
        $text = str_replace("\"", "&quot;", $text); 
        $text = str_replace("'", "&#039;", $text); 
        return $text; 
    } 
}

他们的方式我曾经使用这个:

mysql_query("SELECT * FROM `table` WHERE `username` = '" . $sani($userinput) . "'");

基本上它所做的只是更改可用于注入 html 编码的符号。到目前为止它工作得很好,但是由于我正在迁移到 mysqli,我想知道准备好的语句是否比这个函数更安全。

另外,我已经阅读了很多关于准备好的和未准备好的语句之间的速度差异,真的那么明显吗?我每秒大约进行一百次查询,所以我怀疑我会受到很大影响吗?

谢谢!

4

3 回答 3

4

是的,prepared statements 肯定会比这个函数更安全,而且当你从数据库中取回数据时,它们还有一个额外的好处,那就是不必对数据进行解码。顺便说一句,即使对于旧的 mysql 库,你真的应该依赖mysql_real_escape_string而不是你定制的卫生功能:)

准备好的语句可以比未准备的语句快得多,并且在典型的使用情况下,即使您“只是”每秒执行 100 次查询,您也会从中受益。

于 2012-05-29T18:41:47.870 回答
3

准备好的语句的安全性实际上源于在准备好的语句中,查询数据是分开发送的。这就是为什么不可能执行一种类型的 SQL 注入(第二种类型(或间接)注入是由数据库中的数据连接查询引起的注入)。

您的“保护功能”的问题在于它并未涵盖所有情况。如果您想了解有关该问题的更多信息,您可以阅读 Slides From Recent Presentations on SQL Injection或 slides on SQL injection: Not only AND 1=1中的幻灯片。

于 2012-05-29T19:01:46.317 回答
2

永远不要那样做。

使用准备好的语句按原样保存数据,这样即使数据库中包含恶意代码,您的数据库中也始终拥有原始数据,没问题。事实上,你想看看他们是如何试图入侵你的,或者其他什么。

只需在输出不安全(用户提交的)数据时创建一个简单的过滤器来替换不需要的字符,例如 < > 等。

于 2012-05-29T18:41:32.850 回答