2010-06-14 80 views
10

脚本使用PHP,而DB使用MySQL。这是脚本本身。此查询从sql注入安全吗?

$unsafe_variable = $_GET["user-input"]; 
$sql=sprintf("INSERT INTO table (column) VALUES('%s')",$unsafe_variable); 
mysql_query($sql); 

有人说,如果用户分配;DROP TABLE blah;字符串变量$ unsafe_variable它删除表。

但我试过了这个例子,

http://localhost/test.php?user-input=DROP%20TABLE%20my_table 

但它并没有删除表,而是在表中插入新行(;DROP TABLE blah;)

有人可以解释我怎么可能用sql注入攻击这个脚本?

+3

'mysqli'或'PDO'他们准备的语句会是一个更好的选择。 – Powerlord 2010-06-14 19:29:33

+0

非常感谢所有参与者的问题。我真的意识到,只有'sprintf',我们不能确定我们的查询是否来自** sql注入**。对于这个特定的例子,我和参与者都不能介绍如何执行sql注入。但是我发现了一个很好的sql例子,即使我们使用'sprintf',我们也可以执行sql-injection。这个sql示例可以在这里找到(http://php.net/manual/en/function.mysql-real-escape-string.php“PHP在线手册”)。请参阅'Example#2的一部分示例SQL注入攻击' – Bakhtiyor 2010-06-15 09:41:59

回答

13

由于PHP的mysql_query函数仅允许每次调用一个查询,所以该特定注入将无法工作。但是,以下可以工作,如果column有一个主要或唯一键:

$unsafe_variable = "admin') ON DUPLICATE KEY UPDATE password=MD5(CONCAT('knownsalt', 'newpassword'))#"; 
更好

使用长篇大论mysql_real_escape_string功能:

$sql=sprintf("INSERT INTO table (column) VALUES(%s)", 
      mysql_real_escape_string($unsafe_variable)); 
mysql_query($sql); 
4

mysql_query()不允许在一个函数中执行多个查询。所以你不能INSERT,然后DROP表。但是你不应该依赖这个作为'安全'。改用参数化查询。查看PHP的PDO库。

但是,它们可能会改变其他任何内容,例如可能从另一个表中选择一个密码字段作为子查询放置到该表中,以便他们可以查看散列。

+0

http://php.net/manual/en/function.mysql-query.php – 2010-06-14 19:24:02

+0

downvote的任何原因?准备好的语句通常比'mysql_real_escape_string'安全。 – 2010-06-14 20:13:21

1

不,sprintf的不逃避内容使用:

$unsafe_variable = mysql_real_escape_string($_GET["user-input"]); 
$sql=sprintf("INSERT INTO table (column) VALUES('%s')",$unsafe_variable); 
mysql_query($sql); 
1
mysql_real_escape_string($unsafe_variable) 
3

虽然mysql_query只允许一个查询来执行,一般这个查询是不安全的。一个危险的输入,将利用您的查询的一个例子是:

'); DROP TABLE my_table; -- 

');在一开始就会关闭您的查询,并插入一个空值,但将允许额外的查询INSERT以下执行。然后在放下一张桌子后,最后的--将标记为其他所有内容(即查询的其余部分)作为注释。

为了安全地准备用于查询的输入,请使用mysql_real_escape_string

+0

你是否想说如果我运行这个脚本[http://authoringtool/test.php?user-input =');%20DROP%20TABLE%20my_table2;%20--]它会从我的数据库中删除my_table2?如果没有,请给我一个真实的例子,因为你的例子并没有删除my_table2 :) – Bakhtiyor 2010-06-14 19:29:16

+1

如上所述,'mysql_query'不支持执行多个查询,但你仍然应该正确地保护你的查询。 – 2010-06-14 19:31:15

1

有人说如果用户指定的话; DROP TABLE等于;字符串到变量$ unsafe_variable它删除表。

很明显,情况并非如此 - 但如果您不明白为什么,那么您无法判断您的代码是否安全。你打算在这里发布每一行来检查它的安全吗?如果不对上面的代码做什么以及如何做出妥协(SQL注入已经在其他地方已经有很好的文档记录 - 尝试Google开始),你应该始终确保任何离开你的PHP代码的数据是以正确的方式表示它的去向。

对于MySQL数据库是指:

1)使用mysql_real_escape_string的输出(并确保您传递正确的资源句柄)

2)使用参数绑定。

关于代码注入攻击的适当讨论可以很容易地填充几百页 - 在S.O.中有一点要回答。查询。

C.

0

我想你需要尝试的例子是http://localhost/test.php?user-input=';DROP%20TABLE%20my_table'

');关闭values('%s段,然后发出一个新的命令,drop table...

+0

这不起作用。 – Bakhtiyor 2010-06-15 09:13:05