这个查询容易受到sql注入吗?

use*_*924 5 php sql sql-injection

$myq = sprintf("select user from table where user='%s'", $_POST["user"]);
Run Code Online (Sandbox Code Playgroud)

我想知道是否可以使用SQL注入利用上述查询.是否有任何高级SQL注入技术可以打破sprintf这个特定的查询?

Jon*_*eet 25

我不认为它需要特别先进...尝试输入

' OR 1 = 1 OR user='
Run Code Online (Sandbox Code Playgroud)

换句话说,你会得到以下SQL:

select user from table where user='' OR 1 = 1 OR user=''
Run Code Online (Sandbox Code Playgroud)

这看起来像你真正想要执行的查询吗?(现在考虑它可能会丢弃表,或类似的东西.)

底线是你应该使用参数化查询.

  • 不,不是的.至少不符合我的PHP经验. (2认同)
  • @col.Shrapnel:它不是困扰我们大多数人的投票,而是有人点击按钮说"那个答案不好"而没有提供关于它可能是错误的建议或如何更好地说出来.它可以帮助每个人,如果评论留给任何类型的投票,向上或向下,因为它有助于人们学习和写出更好的答案."权威"徽章的存在是为了鼓励人们留下信息性的评论. (2认同)
  • @col.弹片:我不认为这是关于-2的声誉.而是回答有关改进它的答案有什么问题. (2认同)
  • "最重要的是你应该使用参数化查询." 同意100%.并且SQL注入不是唯一的原因.至少在Oracle中,出于性能原因,应尽可能绑定变量.这样,DB可以重用先前解析的查询和计算的执行计划,并跳过执行计划计算过程中必需的锁定. (2认同)

Gum*_*mbo 8

使用sprintf不会比使用简单的字符串连接更多地提供保护.优点sprintf是它比使用简单的PHP字符串连接时更具可读性.但是sprintf在使用%s格式时,除了简单的字符串连接之外不会做任何事情:

$str = implode('', range("\x00", "\xFF"));        // string of characters from 0x00 – 0xFF
var_dump(sprintf("'%s'", $str) === "'".$str."'"); // true
Run Code Online (Sandbox Code Playgroud)

你需要使用逃避你想要插入数据的上下文特殊字符的函数(在这种情况下是MySQL中字符串声明,假设你正在使用MySQL),如**mysql_real_escape_string**:

$myq = sprintf("select user from table where user='%s'", mysql_real_escape_string($_POST["user"]));
Run Code Online (Sandbox Code Playgroud)


Tim*_*ost 8

是的,我会说你有潜在的问题:)

需要逃避:\x00, \n, \r, \, ', "\x1a.sprintf()不会这样做,sprintf()不对字符串进行修改,它只是根据您指定的格式将您提供的任何可变参数扩展到您提供的缓冲区中.

如果字符串ARE被转换,可能是由于魔术引号(如Rob在评论中所述),而不是sprintf().如果是这种情况,我强烈建议禁用它们.