MyBatis 框架下 SQL 注入审计分析
MyBatis 框架下 SQL 注入审计分析
Diebug前言
SQL 注入漏洞是 Web 安全中最常见的问题之一。在 Java 中,由于预编译技术和各种 ORM 框架的普及,SQL 注入问题虽然有所减少,但仍然存在隐患。对于新手代码审计者而言,面对 Java Web 应用中多个框架的复杂组合,往往无从下手。本文以 MyBatis 框架中使用不当导致的 SQL 注入问题为例,希望能为新手提供一些启发。
一、MyBatis 的 SQL 注入问题
MyBatis 的 SQL 语句可以通过注解写在类的方法上,也可以通过 XML
文件编写。SQL 语句需要手动编写或使用代码生成工具(如 MyBatis
Generator)生成。MyBatis 支持两种参数占位符:#
和
$
,分别表示预编译和字符串拼接。例如:
1 | <select id="queryAll" resultMap="resultMap"> |
其中,#
使用预编译,而 $
则直接拼接
SQL。
在 MyBatis 框架下,易导致 SQL 注入的常见场景包括以下三种:
模糊查询
示例代码:
1
SELECT * FROM news WHERE title LIKE '%#{title}%'
使用
#
会导致程序报错,新手程序员可能会将#
替换为$
。如果在 Java 层面未对用户输入进行有效处理,就可能产生 SQL 注入漏洞。正确写法:
1
SELECT * FROM news WHERE title LIKE CONCAT('%', #{title}, '%')
IN
之后的多个参数示例代码:
1
SELECT * FROM news WHERE id IN (#{ids})
使用
#
处理多个参数会报错,正确做法是使用<foreach>
来遍历参数,而不是简单替换为$
。正确写法:
1
2
3
4SELECT * FROM news WHERE id IN
<foreach collection="ids" item="item" open="(" separator="," close=")">
#{item}
</foreach>ORDER BY
动态排序在这种场景下,建议在 Java 层设置字段或表名的白名单数组,允许用户仅传入合法的索引值,从而避免 SQL 注入。
特别需要注意的是,MyBatis Generator 自动生成的 SQL 中,
ORDER BY
默认使用$
,容易引发注入问题。
二、实战思路
通过分析一个开源 CMS 项目,介绍如何定位和确认 SQL 注入漏洞。
导入项目
在 IDEA 首页选择
Get from Version Control
,输入项目地址https://gitee.com/mingSoft/MCMS.git
,下载完成后等待 Maven 加载依赖。搜索
$
关键字- 使用
Ctrl+Shift+F
搜索 XML 文件中的$
,筛选出可能存在注入风险的代码。 - 以
IContentDao.xml
文件为例,找到多处$
拼接的 SQL 语句,对这些语句逐一进行分析。
- 使用
确定映射关系
- 根据 MyBatis 的
select id
,定位对应的映射对象、实现类和控制层代码。 - 以
getSearchCount
为例,反推调用链找到前台接收的参数,并确认是否存在输入过滤。
- 根据 MyBatis 的
漏洞确认
- 启动项目,构造恶意 SQL 请求,验证是否存在注入漏洞。
- 例如,访问以下 URL:
如果返回数据库版本号
1
http://localhost:8080/ms-mcms/mcms/search.do?categoryId=1') or updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1)#
5.7.27
,则可以确认漏洞存在。
三、总结
以上是 MyBatis SQL 注入审计的基本方法。对于新手,可以尝试分析不同的注入点,熟悉常见的注入场景和防范措施。以下是几个关键点:
- 重点关注三个高危场景:
LIKE
查询、IN
多参数、ORDER BY
动态排序。 - 排查 XML
文件中的
$
:筛选出可能存在注入风险的语句并逐一分析,特别是 MyBatis Generator 自动生成的代码。 - 参数检查:在 Java 层面严格验证用户输入,假定所有输入均为恶意,提前防范潜在攻击。
- 注解 SQL 的审计:方法与 XML 类似,但需要额外关注注解中的动态拼接内容。
通过以上方法,可以有效识别和防范 MyBatis 框架下的 SQL 注入问题。