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

T4N*_*K3R 5 php mysql security sql-injection

PHP:

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

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

小智 15

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

  • 然后使用精益准备的声明.过滤不起作用; 使用参数绑定*总是*. (3认同)

Mar*_*ers 6

我已经考虑了一段时间了,我看不出有任何方法可以将SQL注入到这个语句中.

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

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

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

例如:

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

当使用的参数调用\,并OR 1 = 1 --会导致:

SELECT goodies FROM stash WHERE secret='\' AND secret2=' OR 1 = 1 -- '
Run Code Online (Sandbox Code Playgroud)

哪个MySQL看起来像这样:

SELECT goodies FROM stash WHERE secret='...' OR 1 = 1
Run Code Online (Sandbox Code Playgroud)

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

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