这个查询可以安全地避免 SQL 注入吗?
该脚本使用 PHP 编写,作为数据库,我使用 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 注入来攻击这个脚本吗?
The script is in PHP and as DB I use MySQL. Here is the script itself.
$unsafe_variable = $_GET["user-input"];
$sql=sprintf("INSERT INTO table (column) VALUES('%s')",$unsafe_variable);
mysql_query($sql);
Some people say that if user assigns ;DROP TABLE blah;
string to the variable $unsafe_variable it deletes the table.
But I tried this example,
http://localhost/test.php?user-input=DROP%20TABLE%20my_table
But it didn't delete the table but instead inserted a new row (;DROP TABLE blah;)
in the table.
Could anybody explain me how it is possible to attack this script with sql injections?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
我认为您需要尝试的示例是
http://localhost/test.php?user-input=';DROP%20TABLE%20my_table'
');
关闭values('%s
段,然后发出新命令,drop table...
I think the example you would need to try is
http://localhost/test.php?user-input=';DROP%20TABLE%20my_table'
the
');
closes thevalues('%s
segment, and then issues a new command,drop table...
显然情况并非如此 - 但如果您不明白为什么,那么您就无法判断您的代码是否安全。你要把每一行都贴在这里来检查它是否安全吗?
无需详细解释上面的代码在做什么以及如何破坏它(SQL 注入在其他地方已经有很好的记录 - 首先尝试 Google),您应该始终确保离开 PHP 代码的任何数据都采用正确的表示形式对于它要去的地方。
对于 MySQL 数据库,这意味着:
1)使用 mysql_real_escape_string 的输出(并确保传递正确的资源句柄)
或
2)使用参数绑定。
对代码注入攻击的适当讨论可以轻松地填满数百页 - 在 SO 查询中回答有点多。
C.
Patently that's not the case - but if you don't understand why, then you can't tell if your code is safe. Are you going to post every line here to check if its safe?
Without going into a long explanation about what the code above is doing and how to compromise it (SQL injection is already very well documented elsewhere - try Google for a start) you should ALWAYS ensure that any data leaving your PHP code is in the correct representation for where it is going.
For a MySQL database that means either:
1) use the output of mysql_real_escape_string (and make sure you pass the right resource handle)
or
2) use parameter binding.
A proper discussion of code injection attacks could easily fill several hundred pages - a bit much to answer in a S.O. query.
C.
不, sprintf 不会逃避内容使用:
Nope, sprintf doesn't escape the content use:
处理不安全变量的唯一方法是使用绑定参数。
请阅读 此页面了解如何防止 SQL 注入,来自 bobby-tables.com。
The ONLY way you should be handling unsafe variables is with bind parameters.
Please read this page on how to prevent SQL injection from bobby-tables.com.
虽然
mysql_query
只允许执行一个查询,但一般来说这个查询并不安全。会利用您的查询的危险输入的示例是:开头的
');
将关闭您的查询并插入一个空值,但将允许在 INSERT 之后执行其他查询。然后,在删除表格后,末尾的--
会将后面的所有其他内容(即查询的其余部分)标记为注释。为了安全地准备在查询中使用的输入,请使用
mysql_real_escape_string
。While
mysql_query
only allows one query to execute, in general this query is not safe. An example of a dangerous input that would exploit your query is:The
');
at the start will close your query and insert an empty value, but will allow for additional queries to be executed following the INSERT. Then after dropping a table, the--
at the end will mark everything else following (ie. the rest of your query) as a comment.In order to safely prepare input for use in a query, use
mysql_real_escape_string
.mysql_query()
不允许在一个函数中执行多个查询。所以你不能插入然后删除表。但你不应该依赖它作为“安全”。请改用参数化查询。查看 PHP 的 PDO 库。但是,他们可以更改任何其他内容,例如可能从另一个表中选择密码字段作为子查询放入该表中,以便他们可以查看哈希值。
mysql_query()
doesn't allow the execution of multiple queries in one function. So you can't INSERT and then DROP the table. But you shouldn't rely on this as 'security'. Use parametrized queries instead. Check out PHP's PDO library.However, they could change just about anything else, like possibly SELECTing a password field from another table as a subquery to place into that table so they can view the hash.
由于 PHP 的
mysql_query
函数只允许每次调用一次查询,因此该特定注入不起作用。但是,如果column
具有主键或唯一键,则以下方法可能有效:最好使用冗长的
mysql_real_escape_string
函数:That particular injection wouldn't work since PHP's
mysql_query
function only allows one query per call. However, the following may work ifcolumn
has a primary or unique key:Better to use the long-winded
mysql_real_escape_string
function: