dynamicMySQL查询与SQL转义一样安全的准备语句?

我有一个应用程序,这将大大有益于通过使用dynamicmysql查询结合mysql(mysqli)真正的转义string。 如果我运行从用户收到的所有数据通过MySQL真正的逃生会像使用MySQL准备语句一样安全?

肯定没有。

虽然标题中的问题是模棱两可的, 可以解释为“dynamicMySQL查询与它的每个部分正确格式化 …”,从而有一个积极的答案,身体的问题不是

如果我运行从用户收到的所有数据通过MySQL真正的逃生会像使用MySQL准备语句一样安全?

如果你仔细看这个问题,你会明白,这只是一个魔术引用的化身! 这个不好的,弃用和删除的function的目的正是为了“通过转义运行所有用户input”。
大家都知道,现在的魔语是不好的。 为什么要积极回答呢?

好吧,似乎需要再次解释,为什么批量逃脱是不好的。

问题的根源是一个相当强烈的错觉,几乎每个PHP用户都共享这个错误:
每个人都有一个奇怪的信念:逃避对“危险人物”做些什么(他们是什么?)使他们“安全”(如何?)。 不用说,这只是一个完全的垃圾。

事实是:

  • 逃避不“消毒”任何东西。
  • 逃避与注射无关。
  • 转义与用户input无关。

转义只是一个string格式化 ,没有别的。
当你需要的时候 – 尽pipe有注射的可能性,你仍然需要它。
当你不需要它时 – 即使有一点也不会帮助注射。

说到与准备好的语句的区别,至less有一个问题(已经在sql-injection标签下多次提到过):
这样的代码

 $clean = mysql_real_escape_string($_POST['some_dangerous_variable']); $query = "SELECT * FROM someTable WHERE somevalue = $clean"; 

将帮助你不反对注射。
因为转义只是一个string格式化工具,而不是以任何方式防止注入。
去搞清楚。

然而,转义与预先准备的语句有一些共同之处:
他们都不保证你从注射,如果

  • 你只是使用它而不是臭名昭着的“用户input”,而不是build立任何查询的严格规则,尽pipe数据源。
  • 如果您需要插入不是数据而是标识符或关键字。

为了在这些情况下安全,请参阅我的答案,解释完整的SQL注入保护方法

长话短说:只有当你做了2个重要的更正和一个除了你的初始陈述之外,你可以认为自己是安全的:

如果我通过mysql真正的转义运行从用户接收到的所有数据 并始终把它括在引号 (和,如提到的mysqli_set_charset()mysqli_set_charset()用于使mysqli_real_escapestring()实际上做的工作(在这种罕见的情况下使用一些奇怪的编码像GBK))它会像使用MySQL准备语句一样安全?

遵循这些规则 – 是的,它将像本地准备的语句一样安全。

是的,但合格的是。

你需要正确地逃脱100%的input。 而且你需要正确设置字符集(如果你使用C API,你需要调用mysql_set_character_set()而不是SET NAMES )。 如果你错过了一件小事,你很脆弱。 所以是的,只要你做的一切正确…

这就是很多人会推荐准备好的查询的原因。 不是因为他们更安全。 但是因为他们更宽容

我认为@ircmaxell是正确的。

作为后续工作,请留意这种事情。
我曾经一直这样做:

 <?php //sanitize the dangerous posted variable... $clean = mysql_real_escape_string($_POST['some_dangerous_variable']); //...and then forget to use it! $query = "SELECT * FROM someTable WHERE somevalue = '{$_POST['some_dangerous_variable']}'"; ?> 

而当我说“习惯这样做”时,我的意思是我最终放弃了,并开始使用准备好的语句!