从jshERP来看Mybatis下可能的SQL注入
字数 989 2025-08-25 22:58:56

Mybatis框架下的SQL注入漏洞分析与防范

1. Mybatis框架概述

Mybatis是一款优秀的持久层框架,具有以下特点:

  • 支持定制化SQL、存储过程以及高级映射
  • 避免了几乎所有的JDBC代码和手动设置参数
  • 可以使用XML或注解来配置和映射原生类型、接口和Java对象

为什么需要Mybatis

  • 减少JDBC操作中的重复代码(如数据封装、建立连接等)
  • 提高开发效率
  • 是一个半自动化的ORM框架(对象关系映射)

Mybatis的优点

  1. 简单易学:安装简单,只需两个jar文件和几个SQL映射文件
  2. 灵活:不会对现有设计强加影响,SQL写在XML中便于管理
  3. 解耦:SQL与程序代码分离,提高可维护性
  4. 支持动态SQL

2. Mybatis功能架构

  1. API接口层:提供外部调用接口
  2. 数据处理层:负责SQL查找、解析、执行和结果映射
  3. 基础支撑层:提供连接管理、事务管理、配置加载和缓存处理

3. SQL注入漏洞点分析

关键区别

  • #{}:预编译参数,能有效防止SQL注入
  • ${}:直接拼接SQL语句,存在注入风险

常见易产生SQL注入的场景

1. 模糊查询(LIKE)

错误写法:

select id from users where name like '%#{name}%'

会导致编译错误,开发者可能改为${}导致注入风险

2. IN关键字

错误写法:

select id from users where name in (#{names})

3. ORDER BY子句

错误写法:

order by ${columnName}

4. 漏洞验证示例(jshERP案例)

漏洞定位方法

  1. 全局搜索${}使用点
  2. 确认参数是否可控

实际案例验证

在jshERP的UserMapperEx.xml中:

  • countsByUser方法的${}改为#{}会导致报错
  • 控制台可见错误日志,显示预编译失败
  • 开发者可能被迫改回${}导致注入风险

5. 安全修复方案

1. 模糊查询修复

select id from users where name like concat('%', #{name}, '%')

2. IN关键字修复

select id from users where name in
<foreach collection="names" item="item" open="(" separator="," close=")">
    #{item}
</foreach>

3. ORDER BY修复

  • 使用白名单验证列名
  • 或使用预处理语句(部分数据库支持)

6. 总结与最佳实践

  1. 优先使用#{}:在绝大多数情况下都应使用预编译参数
  2. 谨慎使用${}:仅在确实需要动态SQL且参数安全可控时使用
  3. 特殊场景处理:对于LIKE、IN、ORDER BY等特殊场景,采用框架推荐的安全写法
  4. 代码审计重点:在Mybatis项目中应重点检查上述特殊场景的参数处理方式

通过理解Mybatis的工作原理和常见漏洞模式,开发者可以更安全地使用这一框架,避免SQL注入风险。

Mybatis框架下的SQL注入漏洞分析与防范 1. Mybatis框架概述 Mybatis是一款优秀的持久层框架,具有以下特点: 支持定制化SQL、存储过程以及高级映射 避免了几乎所有的JDBC代码和手动设置参数 可以使用XML或注解来配置和映射原生类型、接口和Java对象 为什么需要Mybatis 减少JDBC操作中的重复代码(如数据封装、建立连接等) 提高开发效率 是一个半自动化的ORM框架(对象关系映射) Mybatis的优点 简单易学:安装简单,只需两个jar文件和几个SQL映射文件 灵活:不会对现有设计强加影响,SQL写在XML中便于管理 解耦:SQL与程序代码分离,提高可维护性 支持动态SQL 2. Mybatis功能架构 API接口层 :提供外部调用接口 数据处理层 :负责SQL查找、解析、执行和结果映射 基础支撑层 :提供连接管理、事务管理、配置加载和缓存处理 3. SQL注入漏洞点分析 关键区别 #{} :预编译参数,能有效防止SQL注入 ${} :直接拼接SQL语句,存在注入风险 常见易产生SQL注入的场景 1. 模糊查询(LIKE) 错误写法: 会导致编译错误,开发者可能改为 ${} 导致注入风险 2. IN关键字 错误写法: 3. ORDER BY子句 错误写法: 4. 漏洞验证示例(jshERP案例) 漏洞定位方法 全局搜索 ${} 使用点 确认参数是否可控 实际案例验证 在jshERP的 UserMapperEx.xml 中: 将 countsByUser 方法的 ${} 改为 #{} 会导致报错 控制台可见错误日志,显示预编译失败 开发者可能被迫改回 ${} 导致注入风险 5. 安全修复方案 1. 模糊查询修复 2. IN关键字修复 3. ORDER BY修复 使用白名单验证列名 或使用预处理语句(部分数据库支持) 6. 总结与最佳实践 优先使用#{} :在绝大多数情况下都应使用预编译参数 谨慎使用${} :仅在确实需要动态SQL且参数安全可控时使用 特殊场景处理 :对于LIKE、IN、ORDER BY等特殊场景,采用框架推荐的安全写法 代码审计重点 :在Mybatis项目中应重点检查上述特殊场景的参数处理方式 通过理解Mybatis的工作原理和常见漏洞模式,开发者可以更安全地使用这一框架,避免SQL注入风险。