为什么MyBatis 3.5中$符号会导致SQL注入漏洞

轻辰大大_7452

轻辰大大_7452

2026-09-01

674人浏览

原创

${}不是漏洞本身,但用在用户可控位置且无校验就是高危SQL注入入口;因其始终为字符串拼接,不经过预编译,攻击者可注入恶意SQL片段,如user; DROP TABLE user--或id, (SELECT password FROM admin),而MyBatis 3.5未改变该行为。

为什么mybatis 3.5中$符号会导致sql注入漏洞

直接说结论:${} 不是漏洞本身,但用在用户可控位置且无校验,就是高危 SQL 注入入口。

为什么 ${} 在 MyBatis 3.5 中仍会触发 SQL 注入

MyBatis 3.5 并未改变 ${} 的底层行为——它仍是字符串拼接,不是预编译。框架升级不会自动修复你代码里写的 ${tableName} 或 ${sortField}。只要参数来自 HTTP 请求、JSON body、前端下拉框 value 等不可信源,又没做白名单校验,攻击者就能塞入 user; DROP TABLE user-- 或 id ASC, (SELECT password FROM admin LIMIT 1) 这类 payload。

常见错误现象:

  • WHERE name = '${name}' → 用户传 admin' OR '1'='1,SQL 变成 WHERE name = 'admin' OR '1'='1'
  • ORDER BY ${field} → 传 created_time, (SELECT @@version),直接拖库或探测数据库版本
  • FROM ${log_table} → 表名被替换为 user_logs UNION SELECT ...,绕过权限限制

哪些地方不得不写 ${},但又最容易翻车

必须用 ${} 的场景极少,集中在 SQL 语法结构层,这些位置 JDBC PreparedStatement 根本不支持参数化:

  • 表名:FROM ${tableName}(#{tableName} 会加引号,变成 FROM 'user_v2026' 报错)
  • 字段名:GROUP BY ${groupField}、SELECT ${countExpr}
  • 排序方向:ORDER BY created_at ${order}(#{order} 会变成 ORDER BY created_at 'desc',按字符串字面值排序)
  • LIMIT 偏移量:LIMIT ${offset}, #{size}(#{offset} 不支持表达式计算)

容易踩的坑:

Photo Booth by Magic Studio
Photo Booth by Magic Studio

Photo Booth by Magic Studio是一款AI图像与设计工具,AI创建个人资料图片。

下载
  • 把 ${@shard_suffix} 当“固定值”用,其实 @shard_suffix 可能来自配置中心,而配置中心本身已被攻破
  • 在 <script></script> 动态 SQL 块里混用 ${} 和 #{},视觉上难分辨,review 时漏掉校验
  • 认为“只在后台管理接口用,前端不暴露,所以安全”,忽略了攻击者可通过低权限账号+未授权接口篡改配置

怎么校验 ${} 才算真正守住底线

校验必须发生在字符串进入 MyBatis 之前,不是进 DAO 层之后,更不是交给数据库执行时才检查。

  • 白名单必须硬编码,例如 List.of("user_logs_2026", "order_events_q3"),禁用从数据库、配置中心、Redis 读取的“可变白名单”
  • 正则校验要严格:^[a-z][a-z0-9_]{2,31}$(小写字母开头、3–32 字符、仅字母数字下划线),拒绝 ..、;、--、空格、大写字母
  • 校验失败立即抛 IllegalArgumentException,不 fallback、不默认值、不记录日志后继续执行
  • 模糊查询别写 LIKE '%${name}%'——通配符必须拼在 Java 层:param.setSearchPattern("%" + userInput.trim() + "%"),SQL 里只用 #{searchPattern}

排查和加固的实操动作

别依赖“我记得都用了 #{}”,真实风险藏在 grep 结果里:

  • 全项目搜索:grep -r '\$\{.*\}' src/main/resources/mapper/ --include="*.xml",把每个 ${} 都拎出来人工过一遍
  • 重点盯三类:${tableName}、${orderBy}、${@xxx}(带 @ 的通常是配置注入点)
  • 检查是否已有校验逻辑:没有就加;有但校验逻辑在 service 层下游(比如进了 DAO 才 check),就往上提,提至 controller 或 DTO 绑定后立刻校验
  • 升级 MyBatis 3.5.x 后注意:@SelectProvider 返回类型更严,原来侥幸跑通的 ${} 错误可能直接报错,这不是 bug,是框架在帮你暴露隐患

最危险的不是找不到修复方法,而是把 ${} 当成“动态语法糖”,忘了它背后是裸字符串拼接——只要输入没锁死,它就是一把没上膛却已对准数据库的枪。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

2023.10.12

5023

8

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.27

1031

4

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

2024.02.23

1329

5

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

7101

10

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

3743

4

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

2024.04.07

7080

11

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

2024.04.29

9921

6

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1350

5

sql中删除一列的命令是什么
sql中删除一列的命令是什么

在sql中,使用alter table语句可以删除一列,语法为:alter table table_name drop column column_name。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1172

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP开发基础之数据库篇(PDO)
PHP开发基础之数据库篇(PDO)

共10课时 | 2.3万人学习