即使转义变量,也会进行SQL注入

时间:2011-10-01 06:51:13

标签: mysql sql mysqli sql-injection

只有当我的查询看起来像示例

时,sql注入才有效
SELECT * FROM login WHERE id = $my_id_va;

假设我的查询是

SELECT * FROM login WHERE id = $my_id_va ORDER BY id DESC

我会得到以下错误

  

#1064 - 您的SQL语法出错;检查手册   对应于您的MySQL服务器版本,以便使用正确的语法   靠近'秩序由id desc'在第1行

那么,这个1 or 1=1; SHOW TABLES不起作用,对吗?

我的网站连续遭到多次黑客攻击。

我想快速回答一下:当我的查询如下所示时,他们可以使用哪些方式或哪种类型的查询来破解我的网站?

SELECT * FROM login WHERE id = $my_id_va ORDER BY id DESC

在以下查询中执行show table的方法有哪些

SELECT * FROM login WHERE id = $my_id_va ORDER BY id DESC

我也使用转义函数来处理查询字符串值,例如mysql_real_escape_string($my_id_va)。是的,显然这是针对单个相关的黑客,但不确定。

增加了一些

SELECT EventActuallyCharged, EventDate FROM tblevent WHERE EventDate between '2011-07-21 or 1=1; SHOW TABLES --' and '2011-07-31' ORDER BY EventDate DESC

但显示表格不起作用

5 个答案:

答案 0 :(得分:2)

如果您使用的是PHP5,请使用参数化查询,请使用PDO。

答案 1 :(得分:2)

Int cast

如果id是数字,您也可以对变量进行整数转换。整数可以安全使用:

$x = (int)$yourInputVar;
$s = "select * from Table where id = $x";

<强> mysql_real_escape_string

如果你想传递一个字符串,你可以,也应该使用mysql_real_escape_string,但这个函数逃脱只有那些字符串中的字符。您仍然需要在字符串周围添加引号,所以:

 $x = mysql_real_escape_string('hello');
 $s = "select * from Table where id = $x";

..将导致查询:select * from Table where id = hello。这是一个有效的查询,因为你好应该用引号。

将查询更改为:

 $x = mysql_real_escape_string('hello');
 $s = "select * from Table where id = '$x'";

..一切正常。你周围添加引号,和mysql_real_escape_string需要照顾的特殊字符里面的字符串,如果有的话。

<强>参数

另一种解决方案是使用参数化查询。这可以使用MySQLi或PDO完成。优点是您只告诉数据库应该插入变量的位置,数据库负责自行转义。

这也可能会增加性能优势,因为这些查询可能没有他们的参数缓存,做出更有效地使用查询缓存。但是,在当前版本的MySQL中,这并没有真正起作用。

答案 2 :(得分:1)

你是对的,1 or 1=1; SHOW TABLES会给出语法错误,但这会有效:

1 or 1=1 --

- 评论查询的其余部分。

在您的情况下,该值为整数,因此您可以使用intval而不是mysql_real_escape_string

答案 3 :(得分:1)

如果您将$my_id_va设置为:

1 or 1=1; SHOW TABLES --

--将注释掉命令的其余部分,从而有效地终止它。

我不确定mysql_real_escape_string对查询会产生什么影响。你应该做的是parameterized queries

答案 4 :(得分:1)

1。第一个查询以某种方式保护

$sql = sprintf('SELECT * FROM login WHERE id = %d ORDER BY id DESC', mysql_real_escape_string($my_id_va));

2。第二个查询以某种方式保护

$sql = sprintf("SELECT EventActuallyCharged, EventDate FROM tblevent WHERE EventDate BETWEEN '%s' AND '%s' ORDER BY EventDate DESC", 
             mysql_real_escape_string($start_date),
             mysql_real_escape_string($end_date));

如果您不理解,请阅读有关sprintf的文档。

但是,正如其他人所说,如果您将参数化查询与PDOMySQLi等类一起使用,那将非常安全。