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

mybatis-plus SQL 注入漏洞导致版本升级引发的问题

前言

最近做项目,对于企业级而言 JDK 和 Spring 的升级不能一蹴而就,而且 OpenJDK11 的支持时间不多了,升级到 JDK17 风险太大,所以缝缝补补,但是mybatis-plus 需要升级,这个就没办法了,其实这次漏洞影响的是 QueryWrapper 或者 UpdateWrapper 在动态 SQL 时通过调用方法com.baomidou.mybatisplus.core.toolkit.sql.SqlInjectionUtils检查是否特殊 SQL 字符防注入。本身是日常升级,但是升级出事了。

准备 demo

POM

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.7.18</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.36</version></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.3.2</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId><version>2.7.18</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.7</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.7</version></dependency></dependencies>

随便写个 demo

@Mapper
public interface DemoDao {@Select("select * from user where name = #{name}")List<User> selectUser(String name);
}@RestController
public class DemoController {@Autowiredprivate DemoDao demoDao;@RequestMapping("/user")public List<User> listUser(String name){return demoDao.selectUser(name);}
}@SpringBootApplication
@MapperScan(basePackages = "com.boot.mybatis.plus.demo.dao")
public class MybatisPlusMain {public static void main(String[] args) {SpringApplication.run(MybatisPlusMain.class, args);}
}

配置一个数据源即可

jar 冲突 1

启动上面是示例,发现失败了,原因是 mybatis-plus 的 3.5.7 和 mybatis 的 3.5.7 冲突,mybatis 3.5.7 较旧

2025-11-03 21:12:38.910 ERROR 1625 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : ***************************
APPLICATION FAILED TO START
***************************Description:An attempt was made to call a method that does not exist. The attempt was made from the following location:com.baomidou.mybatisplus.core.MybatisMapperAnnotationBuilder$AnnotationWrapper.<init>(MybatisMapperAnnotationBuilder.java:653)The following method did not exist:org.apache.ibatis.annotations.Select.affectData()ZThe calling method's class, com.baomidou.mybatisplus.core.MybatisMapperAnnotationBuilder$AnnotationWrapper, was loaded from the following location:jar:file:/Users/huahua/.m2/repository/com/baomidou/mybatis-plus-core/3.5.7/mybatis-plus-core-3.5.7.jar!/com/baomidou/mybatisplus/core/MybatisMapperAnnotationBuilder$AnnotationWrapper.classThe called method's class, org.apache.ibatis.annotations.Select, is available from the following locations:jar:file:/Users/huahua/.m2/repository/org/mybatis/mybatis/3.5.7/mybatis-3.5.7.jar!/org/apache/ibatis/annotations/Select.classThe called method's class hierarchy was loaded from the following locations:org.apache.ibatis.annotations.Select: file:/Users/huahua/.m2/repository/org/mybatis/mybatis/3.5.7/mybatis-3.5.7.jarAction:Correct the classpath of your application so that it contains compatible versions of the classes com.baomidou.mybatisplus.core.MybatisMapperAnnotationBuilder$AnnotationWrapper and org.apache.ibatis.annotations.Select

查看源码发现

根据 maven 仓库分析

mybatis-plus 3.5.7 依赖 mybatis3.5.16

jar 冲突 2

升级 mybatis 版本到 3.5.16 后,如果同时使用 spring-data-jpa,那么 jsqlparser 就会冲突

本身而言只有 mybatis-plus 强依赖这个 jar,但是实际上 spring-data-jpa(除了 CN 基本上都是使用 jpa) 也隐形的依赖了这个 jar,且版本号与 mybatis-plus 不一样

但是是 optional,但是又是 provided 修饰

在org.springframework.data.jpa.repository.query.QueryEnhancerFactory中就会判断

发现有些类不存在,如果引入了 spring-data-jpa,不使用 jpa还好,如果使用则会 启动报错

解决办法有 2 个:

  • mybatis-plus 排除 jsqlparser
  • 使用低版本的 jsqlparser,比如 3.1,既不能使用 mybatis-plus 依赖的高版本,也不能使用 spring-data-jpa 的 4.5 版本,不兼容

QueryWrapper IN 查询

@Mapper
public interface DemoDao {@Select("select * from User ${ew.customSqlSegment}")List<User> selectUser(@Param(Constants.WRAPPER) QueryWrapper<User> queryWrapper);
}@RequestMapping("/user")public List<User> listUser(String name){QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.in("name", Collections.emptySet());return demoDao.selectUser(queryWrapper);}

适当改造代码,执行 http 访问

### Error querying database.  Cause: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '))' at line 1
### The error may exist in com/boot/mybatis/plus/demo/dao/DemoDao.java (best guess)
### The error may involve com.boot.mybatis.plus.demo.dao.DemoDao.selectUser-Inline
### The error occurred while setting parameters
### SQL: select * from User WHERE (name IN ())
### Cause: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '))' at line 1
; bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '))' at line 1] with root causejava.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '))' at line 1

SQL:select * from User WHERE (name IN ())

这个在 mybatis-plus 3.4 以下的版本可以正常运行,先看看 mybatis-plus 3.4 与之后的逻辑

其实 mybatis-plus 已经明确说明了,看看代码

看看 SQL 是怎么拼接的,因为是动态 SQL,所以每次动态拼接

org.apache.ibatis.parsing.GenericTokenParser

同理这里可以配置过滤器检查 SQL

看看 mybatis-plus 3.3.2 呢

其实为 null 会空指针,只有空集合元素才会不拼接

所以 mybatis-plus 3.4 以下不会出现问题,当然可能空指针

总结

mybatis-plus 真是一言难尽啊,国外基本上是使用 jpa,其实 mybatis 也有 jpa,mybatis-plus 和 spring-data-jpa 存在 jsqlparser 隐形冲突,mybatis-plus 和 mybatis 对相同 id 的处理不一样:https://blog.csdn.net/fenglllle/article/details/134912102。升级后 QueryWrapper IN处理空集合的逻辑不一样,这种需要全覆盖测试才行,否则特殊数据就......建议为了减少问题,只使用一样,比如 mybatis-plus 与 spring-data-jpa 二选一,另外尽量不使用 query wrapper 这样的动态 SQL 拼接,建议使用代码动态拼接。

http://www.dtcms.com/a/565254.html

相关文章:

  • 低空经济爆发期 遥感影像识别如何破解数据安全与效率困局
  • 哈尔滨做平台网站平台公司哪家好南通启益建设集团有限公司网站
  • 可以做婚礼视频的网站有哪些免费域名注册可解析
  • 网络抓包教学
  • Input getevent记录和InputReader,InputDispatcher启动
  • ESP01s通过blinker云端进行远程控制开关灯
  • 前端面试高频题解析
  • 模板网站修改教程南宁cms建站系统
  • 中天建设集团网站WordPress好像微博一样插件
  • 果蔬检测数据集VOC+YOLO格式16099张72类别
  • 电子沙盘数字沙盘智能吸附工具栏:高效作战新利器7
  • 关于asp sql网站开发的书籍微梦网站建设
  • 突破局域网限制!EMQX 结合 cpolar 实现 MQTT 远程通信全攻略
  • 【经典书籍】《人月神话》第八章“胸有成竹”精华讲解
  • 升级mybatis-plus导致项目启动报错: net.sf.jsqlparser.statement.select.SelectBody
  • 线性代数 - 线性方程组的原始解法(高斯消元法)
  • 深入 Lua 环境机制:全局变量的 “容器” 与 “隔离术”
  • 利用Github与Hexo搭建属于自己的在线个人博客
  • 哪些网上订餐的网站做的好模板网站 建设教材
  • 【每天一个AI小知识】:什么是零样本学习?
  • 清理WSL2下的docker磁盘docker_data.vhdx的长期增长的容量问题
  • AOI在化学药剂检测领域中的应用
  • 【IC】NoC设计入门 -- 拓扑
  • wordpress主题怎么选电商seo搜索引擎优化
  • DGX Spark 恢复系统
  • 【分布式锁通关指南 12】源码剖析redisson如何利用Redis数据结构实现Semaphore和CountDownLatch
  • 绵阳网站推广排名新网站快速排名软件
  • 矿山通信如何实现全域一体化?迈威为煤矿装上了“智慧神经网络”
  • 不止于Linux:百花齐放的开源世界与社区的力量
  • python grammar : case sensitive, python Python