脚本是用PHP编写的,而DB用的是MySQL。这是脚本本身。
$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注入来攻击这个脚本吗?
答案 0 :(得分: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);
答案 1 :(得分:4)
mysql_query()
不允许在一个函数中执行多个查询。所以你不能INSERT然后DROP表。但你不应该把它当作“安全”。请改用参数化查询。查看PHP的PDO库。
但是,它们可以改变其他任何东西,例如可能从另一个表中选择一个密码字段作为子查询放入该表,以便他们可以查看散列。
答案 2 :(得分:3)
虽然mysql_query
只允许执行一个查询,但通常此查询不安全。可以利用您的查询的危险输入示例如下:
'); DROP TABLE my_table; --
开头的');
将关闭您的查询并插入一个空值,但允许在INSERT之后执行其他查询。在删除表之后,最后的--
会将其他所有内容(即查询的其余部分)标记为注释。
为了安全地准备要在查询中使用的输入,请使用mysql_real_escape_string
。
答案 3 :(得分:2)
您应该处理不安全变量的唯一方法是使用绑定参数。
请从this page on how to prevent SQL injection阅读bobby-tables.com。
答案 4 :(得分:1)
不,sprintf不会逃避内容使用:
$unsafe_variable = mysql_real_escape_string($_GET["user-input"]);
$sql=sprintf("INSERT INTO table (column) VALUES('%s')",$unsafe_variable);
mysql_query($sql);
答案 5 :(得分:1)
mysql_real_escape_string($unsafe_variable)
答案 6 :(得分:1)
有人说如果用户指定; DROP TABLE等等;字符串到变量$ unsafe_variable它删除表。
显然情况并非如此 - 但如果您不明白为什么,那么您无法判断您的代码是否安全。你打算在这里张贴每一行来检查它是否安全吗?
没有详细解释上面的代码正在做什么以及如何妥协它(SQL注入已在其他地方很好地记录 - 尝试谷歌开始)你应该始终确保任何离开你的PHP代码的数据都在正确表示它的去向。
对于MySQL数据库,这意味着:
1)使用mysql_real_escape_string的输出(并确保传递正确的资源句柄)
或
2)使用参数绑定。
对代码注入攻击的正确讨论可以很容易地填充数百页 - 在S.O.中有点回答。查询。
下进行。
答案 7 :(得分:0)
我认为您需要尝试的示例是http://localhost/test.php?user-input=';DROP%20TABLE%20my_table'
');
关闭values('%s
段,然后发出新命令drop table...