SQL注入 - 这个(oneliner)安全吗?

时间:2010-08-14 20:01:00

标签: php mysql security sql-injection

PHP:

$SQL = "SELECT goodies FROM stash WHERE secret='" .  
    str_replace("'",'',$_POST['secret']) .  
"'";  

一个邪恶的天才黑客可以将SQL注入我的SELECT - How?

4 个答案:

答案 0 :(得分:14)

为什么不使用mysql_real_escape_string()甚至更好的预处理语句?你的解决方案似乎很愚蠢。

答案 1 :(得分:6)

我已经考虑了一段时间了,我看不出任何方法将SQL注入此声明。

以单引号开头的SQL字符串将在下一个单引号处终止,除非使用反斜杠或其他引号(\''')进行转义。由于您要删除所有单引号,因此不能使用加倍的引号。如果你逃避收尾报价,你将收到一个错误,但没有SQL注入。

然而,这种方法有许多缺点:

  • 输入中的单引号将被忽略。
  • 输入中的反斜杠未正确处理 - 它们将被视为转义码。
  • 如果最后一个字符是反斜杠,则会出错。
  • 如果稍后扩展查询以添加第二个参数,允许SQL注入攻击。

例如:

$SQL = "SELECT goodies FROM stash WHERE secret='" .  
    str_replace("'",'',$_POST['secret']) .  
"' AND secret2 = '" .
    str_replace("'",'',$_POST['secret2']) .  
"'";  

使用参数\OR 1 = 1 --调用时会产生:

SELECT goodies FROM stash WHERE secret='\' AND secret2=' OR 1 = 1 -- '

MySQL会看到这样的事情:

SELECT goodies FROM stash WHERE secret='...' OR 1 = 1

即使在这种情况下不可能引起注入,但缺点使得这种方法不适用于避免SQL注入的通用方法。

正如已经指出的那样,解决方案是使用准备好的声明。这是防止SQL注入攻击的最可靠方法。

答案 2 :(得分:0)

可能是。 最好的方法是:

$query = sprintf("SELECT goodies FROM stash WHERE secret='%s'",
addcslashes(mysql_real_escape_string($_POST['secret']),'%_'));

答案 3 :(得分:-1)

为什么不使用mysql_escape_string?是的,他可以,添加"而不是'加上,我猜这个查询会给你一个错误。