我有一个应用程序,通过结合mysql(mysqli)真正的转义字符串使用动态mysql查询将大大受益。如果我通过mysql运行从用户收到的所有数据真正的转义它是否与使用mysql预处理语句一样安全?
答案 0 :(得分:17)
是的,但是合格的是。
您需要正确地逃避100%的输入。您需要正确设置字符集(如果您使用的是C API,则需要调用mysql_set_character_set()
而不是SET NAMES
)。如果你错过了一件小事,那你很脆弱。所以是的,只要你做的一切都正确......
这就是很多人会推荐准备好的查询的原因。不是因为它们更安全。但因为他们更宽容......
答案 1 :(得分:4)
虽然标题中的问题含糊不清,可以被解释为“动态的mysql查询每个部分正确格式化 ... “因此有一个肯定的答案,身体中的问题是不:
如果我通过mysql运行从用户收到的所有数据真正的转义它是否与使用mysql预处理语句一样安全?
如果你仔细看看这个问题,你会明白这只是一个魔术引语化身!这种耻辱,弃用和删除功能的目的正是“通过转义运行所有用户输入” 现在每个人都知道魔术引用很糟糕。 为什么积极回答呢?
好吧,它似乎需要再次解释,为什么批量转义是坏的。
问题的根源是一个非常强烈的错觉,几乎每个PHP用户都共享:
每个人都有一种奇怪的信念,即逃避对“危险角色”做什么(他们是什么?)使他们“安全”(怎么样?)。不用说,这只是一个完全垃圾。
事实是:
转义只是一个字符串格式而没有别的 当您需要它时 - 尽管注射可能,但您需要它 当你不需要它时 - 即使是一点也不会有助于注射。
说到与准备好的陈述的区别,至少有一个问题(已在sql-injection
标签下多次提及):
像这样的代码
$clean = mysql_real_escape_string($_POST['some_dangerous_variable']);
$query = "SELECT * FROM someTable WHERE somevalue = $clean";
将帮助您免受注射 因为逃避只是一个字符串格式化设施,而不是任何方式的防喷器 去搞清楚。
然而,逃避与准备好的陈述有一些共同点:
如果
为了安全起见,请参阅我的回答解释FULL sql injection protection how-to
长话短说:只有在对初始陈述做出两个必要的更正和一个补充时,你才能认为自己是安全的:
如果我通过mysql真实转义运行从用户收到的所有数据
并始终将其括在引号中(并且,正如ircmaxell所述,使用mysqli_set_charset()
使mysqli_real_escape string()实际上做它的工作(在极少数情况下使用像GBK这样的奇怪编码))它是否与使用mysql预处理语句一样安全?
遵循这些规则 - 是的,它将与本机准备的语句一样安全。
答案 2 :(得分:1)
我认为@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']}'";
?>
当我说“习惯做”时,我的意思是我最终放弃并开始使用准备好的陈述!