当前位置: 首页 > news >正文

MyBatis Example模式SQL注入风险

在使用MyBatis逆向工程生成的Example查询模式时,很多开发者看到XML中存在${}占位符就会担心SQL注入问题。但实际上,存在${}并不等同于存在SQL注入风险。本文将详细分析何时会存在真正的注入风险。

存在SQL注入的两个关键前提

前提一:Criteria存在自定义扩展且接受外部输入

MyBatis Generator生成的标准Criteria类是相对安全的,但如果开发者添加了自定义扩展方法,就可能引入风险:

// 危险的自定义扩展示例
public class MTaxSbPayExample {public static class Criteria extends GeneratedCriteria {// ❌ 危险:允许用户直接传入SQL条件public Criteria andCustomCondition(String sqlCondition, Object value) {addCriterion(sqlCondition, value, "custom");return (Criteria) this;}// ❌ 危险:动态表名或列名public Criteria andDynamicColumn(String columnName, String operator, Object value) {addCriterion(columnName + " " + operator, value, columnName);return (Criteria) this;}}
}

如果用户输入直接传递给这些方法:

// 恶意输入示例
String userInput = "1=1; DROP TABLE users;--";
example.createCriteria().andCustomCondition(userInput, "someValue");

前提二:Example对象作为接口参数且orderByClause被不当赋值

另一个风险点是orderByClause字段,因为ORDER BY子句通常需要使用${}来处理列名:

<if test="orderByClause != null">order by ${orderByClause}
</if>

危险场景:

// ❌ 危险:直接将用户输入作为排序条件
@RestController
public class DataController {public List<MTaxSbPay> getData(@RequestParam String sortBy) {MTaxSbPayExample example = new MTaxSbPayExample();// 直接使用用户输入,存在注入风险example.setOrderByClause(sortBy);  return mapper.selectByExample(example);}
}

恶意请求:

GET /getData?sortBy=id; DROP TABLE users;--

为什么存在${}不一定有SQL注入风险

1. 硬编码的安全使用

在标准的MyBatis Generator实现中,${criterion.condition}中的condition是硬编码的:

// 生成的安全方法
public Criteria andIdEqualTo(String value) {addCriterion("ID =", value, "id");  // "ID =" 是硬编码字符串return (Criteria) this;
}

对应的XML处理:

<when test="criterion.singleValue">and ${criterion.condition} #{criterion.value}
</when>

最终生成安全的SQL:

WHERE ID = ?  -- 参数: 用户输入值

2. 参数分离的设计模式

MyBatis Generator采用了条件与参数分离的设计:

  • 条件部分${criterion.condition}):硬编码的操作符,如=>LIKE
  • 参数部分#{criterion.value}):用户输入,通过参数化查询处理

这种设计确保了即使使用${},也不会直接拼接用户输入的内容。

3. 用户输入路径受限

标准的Criteria类只提供预定义的方法:

// 用户只能通过这些安全的方法构建查询
criteria.andIdEqualTo(userInput);      // 安全
criteria.andNameLike("%" + userInput + "%");  // 安全  
criteria.andStatusIn(Arrays.asList("ACTIVE", "INACTIVE"));  // 安全

用户无法直接控制criterion.condition的值,只能影响criterion.value,而后者是参数化处理的。

总结

MyBatis的${}占位符本身并不等同于SQL注入漏洞。关键在于:

  • 数据来源:是硬编码还是用户输入?
  • 使用方式:是否进行了适当的验证和过滤?
  • 设计模式:是否采用了参数分离的安全设计?

标准的MyBatis Generator生成的Example代码通常是安全的,真正的风险往往来自于开发者的不当扩展和使用。

http://www.xdnf.cn/news/1478251.html

相关文章:

  • C#中一段程序类比博图
  • 【完整源码+数据集+部署教程】水培植物病害检测系统源码和数据集:改进yolo11-AKConv
  • 从 JDK 1.8 切换到 JDK 21 时遇到 NoProviderFoundException 该如何解决?
  • 【科研成果速递-IJGIS】如何描述与分类移动对象的时空模式?一个新的分类框架与体系!
  • JDBC操作数据库所需要的组件
  • 《Kubernetes 构建 MySQL MGR 集群实战教程》
  • 使用Spring Boot DevTools快速重启功能
  • Python爬虫实战:研究Event Handling机制,构建在线教育平台的课程数据采集和分析系统
  • 使用 YAML 自动化 Azure DevOps 管道
  • browser-use 的三种启动方式详解
  • Android Framework智能座舱面试题
  • 【Python自动化】 21.2 Pandas 读取 Excel 时的 dtype 参数完全指南
  • 贪心算法应用:DNA自组装问题详解
  • Flask论坛与个人中心页面开发教程完整详细版
  • 【LeetCode 热题 100】49. 字母异位词分组
  • Windows 11 手动下载安装配置 uv、配置国内源
  • 固定资产管理系统(vue+Springboot+mybatis)
  • 行为式验证码技术解析:滑块拼图、语序选词与智能无感知
  • Vllm-0.10.1:vllm bench serve参数说明
  • 【完整源码+数据集+部署教程】农作物病害检测系统源码和数据集:改进yolo11-HSFPN
  • Flutter常用库集锦
  • Webpack热更新(HMR)底层原理详解
  • 基于定制开发开源AI智能名片S2B2C商城小程序的DMP平台离线文件上传功能优化研究
  • RK3568 Trust
  • 进程间通信(IPC)方式
  • AgentScope 1.0深度解析:技术架构、使用教程与多智能体开发实践
  • 跟着开题报告学答辩!《 Access学情分析系统的设计与实现》开题答辩实录分享!
  • Linux系统编程守护进程(36)
  • Linux笔记---TCP套接字编程
  • Docker学习笔记-网络类型