问题的发现
最近在对公司后台代码安全审计的过程中,发现了一种有意思的缝隙类型,一种依据排序的SQL猜解进犯问题,咱们且抽一段片段代码来看一下
"queryUsers" resultType="com.huobi.open.mis.dao.Users">
select u.user_id, u.username, u.email, u.mobile, u.status,u.password_status from crm_user
where>
if test="username != null and username.trim() != ''">
and u.`username` like concat('%',#{username},'%')
if>
if test="userId != null and userId != ''">
and u.`user_id` != #{userId}
if>
where>
test="sidx != null and sidx.trim() != ''">
order by u.${sidx} ${order}
order by u.user_id desc
if test="offset != null and limit != null">
limit #{offset}, #{limit}``
if>
假如直接观测这段代码,好像有SQL注入的问题,在Spring的,SPEL表达式 # 相当于占位符,这有用的避免SQL注入的发作,所以一般关于mapper的审计,咱们就观测是否有运用 $ 的当地,在依据对应的id去追溯运用到它的代码,检查是否有SQL注入
@Pattern(regexp = "^(?i)DESC|(?i)ASC$",name="排序",message = "order不合法")
持续追寻代码,所以发现程序对 sidx 和 order 做了安全校验,这好像没有什么问题了, 所以这一处就通过了SDL团队的安全测验。可是再持续追溯起来我发现这段代码仍然存在安全问题,由于它尽管避免了SQL注入进犯,可是它没有对排序字段做约束,这就存在了一个问题
当我妄图运用password进行排序的时分,服务器成功返回了数据,那么这意味着我可以运用order by进行排序进犯,举个比如,咱们查询一张惯例的用户表
mysql> select * from crm_user;
+-----+----------+--------------+
| uid | username | password |
+-----+----------+--------------+
| 1 | 111 | 111 |
| 2 | enoch | apple |
| 3 | sam | boomsakalaka |
| 4 | belln | zipzip |
| 5 | mosuan | 123456 |
| 6 | xsseng | 123456 |
+-----+----------+--------------+
6 rows in set (0.00 sec)
咱们依据password对数据进行升序排序,就会发现数据由暗码的首字符1-9a-z如此升序排序
mysql> select * from crm_user order by password asc;
+-----+----------+--------------+
| uid | username | password |
+-----+----------+--------------+
| 1 | 111 | 111 |
| 5 | mosuan | 123456 |[1][2]黑客接单网