🎯 MyBatis执行SQL的深入分析
✅ MyBatis注入链路结构
[Controller] → [Service] → [DAO] → [Mapper(XML/注解)] → [SQL执行]
📌 注入可能发生在:Mapper 的 SQL 映射中
-
使用 ${}
:直接拼接输入参数,存在 SQL 注入风险。 -
使用 #{}
:预编译处理参数,安全。
🧪 示例场景:用户查询功能存在SQL注入漏洞
👇 1. Controller 层
@RestController@RequestMapping("/admin")publicclassAdminController{@Autowiredprivate AdminService adminService;@GetMapping("/search")public List<Admin> search(@RequestParam String username){return adminService.searchByUsername(username); }}
-
用户访问: /admin/search?username=admin
-
参数传入 Service 层
👇 2. Service 层
@ServicepublicclassAdminService{@Autowiredprivate AdminDAO adminDAO;public List<Admin> searchByUsername(String username){return adminDAO.findByUsername(username); }}
-
调用 DAO,无输入校验
👇 3. DAO 层
@RepositorypublicclassAdminDAO{@Autowiredprivate AdminMapper adminMapper;public List<Admin> findByUsername(String username){return adminMapper.selectByUsername(username); }}
👇 4. Mapper 接口
publicinterfaceAdminMapper{List<Admin> selectByUsername(@Param("username") String username);}
👇 5. Mapper XML 配置(存在注入风险)
<selectid="selectByUsername"parameterType="String"resultType="Admin"> SELECT * FROM admin WHERE username = '${username}'</select>
🔴 实际SQL:
SELECT * FROMadminWHERE username = 'admin'OR'1'='1'
💥 构造攻击Payload
/admin/search?username=admin' OR '1'='1
可绕过身份验证,查询全部用户。
🔧 安全修复建议
<selectid="selectByUsername"parameterType="String"resultType="Admin"> SELECT * FROM admin WHERE username = #{username}</select>
✅ #{}
使用预编译参数,防止注入。
🔍 审计步骤
-
🔍 查找输入入口(Controller) -
🔗 跟踪参数传递链(Service → DAO → Mapper) -
📄 审计 Mapper XML/注解中的 SQL -
🧪 构造Payload测试是否可注入
🛡 防御建议汇总
风险点 | 修复方式 | 说明 |
---|---|---|
${param} |
替换为 #{param} |
避免字符串拼接 |
order by 动态排序 |
<choose> 限制字段选择 |
控制字段范围 |
like 模糊查询 |
使用 CONCAT('%', #{value}, '%') |
安全拼接 |
in 条件查询 |
使用 <foreach> 实现集合传参 |
安全高效 |
🔚 总结
MyBatis 的 SQL 注入常因 ${}
使用不当或动态SQL拼接导致,从 Controller 到 XML 是一条完整的攻击链。修复建议:
-
全面替换 ${}
为#{}
; -
动态语句使用白名单控制; -
对高风险字段进行正则验证; -
辅以全局过滤器提升防御强度。
💡不过在日常审计中,我们通常会:
-
借助代码扫描器定位关键词,如注解或 XML 配置中的
${}
-
从 Mapper 层 反向追踪至 Controller 层
-
判断是否存在参数拼接、SQL 注入等安全问题
原文始发于微信公众号(季升安全):一文吃透 MyBatis 执行 SQL 的全过程,附源码解析!
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论