为什么感觉在实际的测试中ORDER BY注入的比例变高了

之前去阿里先知大会的时候, 在听greg.wu的议题的时候, 听到他提了一下他挖order by注入的比例占所有注入比例的20-30%(如果没记错的话)

自己在各种测试的过程中,发现的order by注入也确实不少, 每次看到order,sort之类的参数都会有点小兴奋。

那为什么在现在sql注入越来越少的情况下,order by注入的比例还不低呢。

我感觉是因为常见的查询,直接自己预编译或者用框架里的一些方法就能防止掉注入。
但是order by time这种排序是不能通过直接预编译来搞的,
因为如果直接像java里的preparestement来预编译,
order by ?, setString(1,”time”);
最后的sql语句就变成了order by “time”, 对一个字符串排序是没有效果的,所以一些人就又直接把order拼接之类的导致了注入。
而且order by 这种排序在程序中却用得不少, 因为有时候要根据用户的要求来排序, 就像网上商城那种即可以用销量来对商品进行排序,也可以用价格之类的来排序, 这时候就得根据用户传递进来的值来进行相应的排序.

那么一般是如何来防止ORDER BY注入的呢。
如果不利用框架来防止的话,我见过比较常用的两种是

1:从数据库中查询出来要排序的表中的所有列, 或者就是指定的几个列名,如果用户传递的sort变量不在允许的范围内的话,再把sort变量重置一下。

1
2
3
4
$sort = $_GET['sort'];
if(!in_array($sort,array('time','price'))){
$sort = 'time';
}

2:还见得比较多的一种就是用户直接传的是数字, 不过以下这种写法,千万别忘啦default,没default的话,又注入咯。

1
2
3
4
5
6
7
8
9
10
11
12
$sort = $_GET['sort'];
switch($sort){
case 1:
$sort = 'time';
break;
case 2:
$sort = 'price';
break;
default:
$sort = 'time';
break;
}

至于框架对于order by的防御, 有一些框架有防御, 部分没有。

我见过的两种框架防御order by注入的
一种是判断用户传递的是不是实体类的属性(hibernate),

如果order的参数不是实体类里的属性就直接报错了。

还有一种就是 用户传递进去的字符串, 给你强行加上` ,再对用户传递进来的字符串清掉` , 或者对`转义