只有当我的查询看起来像示例
时,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
但显示表格不起作用
答案 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)
$sql = sprintf('SELECT * FROM login WHERE id = %d ORDER BY id DESC', mysql_real_escape_string($my_id_va));
$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
的文档。