Mybatis框架下SQL注入审计分析
字数 1229 2025-08-15 21:31:21
Mybatis框架下SQL注入审计分析教学文档
一、Mybatis框架SQL注入概述
SQL注入是WEB安全中最常见的漏洞之一。在Java应用中,随着预编译与ORM框架的使用,注入问题有所减少,但Mybatis框架使用不当仍可能导致SQL注入漏洞。
Mybatis参数符号机制
- #{}:使用预编译方式,能有效防止SQL注入
- ${}:直接拼接SQL语句,存在SQL注入风险
二、Mybatis易产生SQL注入的三种场景
1. 模糊查询(like语句)
错误写法:
<select id="queryAll" resultMap="resultMap">
SELECT * FROM NEWS WHERE title LIKE '%#{title}%'
</select>
这种写法会导致程序报错,开发者可能错误地将#改为$,从而引入注入风险。
正确写法:
<select id="queryAll" resultMap="resultMap">
SELECT * FROM NEWS WHERE title LIKE concat('%', #{title}, '%')
</select>
2. IN子句查询
错误写法:
<select id="queryAll" resultMap="resultMap">
SELECT * FROM NEWS WHERE id IN (#{ids})
</select>
正确写法:
<select id="queryAll" resultMap="resultMap">
SELECT * FROM NEWS WHERE id IN
<foreach collection="ids" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>
3. ORDER BY子句
风险写法:
<select id="queryAll" resultMap="resultMap">
SELECT * FROM NEWS ORDER BY ${columnName}
</select>
安全建议:
- 在Java层面做字段名映射
- 设置字段/表名白名单
- 仅允许用户传入索引值而非直接字段名
特别注意:mybatis-generator自动生成的SQL语句中,order by默认使用$符号
三、Mybatis SQL注入审计实战方法
1. 审计流程
- 搜索xml文件查找可能存在注入的漏洞点
- 反推到DAO层
- 追踪到实现类
- 通过调用链找到前台URL
- 确认利用点
2. 具体审计步骤
第一步:导入项目
- 使用IDEA导入目标项目
- 等待Maven依赖下载完成
第二步:搜索$关键字
- 使用Ctrl+Shift+F调出全局搜索
- 筛选后缀为xml的文件
- 搜索$关键字
- 重点关注文件名带Dao的xml文件
第三步:分析潜在注入点
- 排除数据库选择语句
- 重点关注:
- ORDER BY后的$
- 普通拼接语句中的$
- IN和LIKE语句中的$
第四步:追踪调用链
- 通过select id找到映射对象名
- 搜索映射对象(通常为XXXDao.java)
- 查找对应的实现类(XXXDaoImpl.java)
- 追踪到前端Controller
- 确认参数传递路径
第五步:验证参数处理
- 检查前端参数接收方式
- 确认是否对参数进行安全处理
- 特别关注直接使用BasicUtil.getString等未做过滤的方法
第六步:漏洞确认
构造测试Payload验证注入是否存在,例如:
http://localhost:8080/ms-mcms/mcms/search.do?categoryId=1') or updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1)#
四、防御建议
-
代码层面:
- 尽量使用#{}而非${}
- 对于必须使用${}的场景,严格过滤用户输入
- 建立字段名白名单机制
-
审计层面:
- 重点关注LIKE、IN和ORDER BY语句
- 对mybatis-generator生成的代码要特别检查ORDER BY
-
开发规范:
- 假定所有用户输入均为恶意输入
- 实施参数化查询原则
- 对动态SQL进行严格的输入验证
五、总结
Mybatis框架下的SQL注入审计需要重点关注:
- 三种高风险场景:LIKE、IN和ORDER BY
- XML方式编写SQL时,优先搜索$符号定位风险点
- 注解方式编写SQL时采用类似审计方法
- Java层面应实施严格的参数检查机制
通过系统化的审计方法和防御措施,可以有效降低Mybatis应用中的SQL注入风险。