MyBatis 怎么在 XML 中使用 `` 标签防止 SQL 注入

轻瑶君_1165

轻瑶君_1165

2026-08-09

175人浏览

原创

mybatis 的 标签本身不防 sql 注入,仅用于绑定 ognl 表达式结果为变量;其安全性取决于后续引用方式:配合 #{}(预编译)则安全,配合 ${}(字符串替换)仍会注入。

mybatis 怎么在 xml 中使用 `<bind>` 标签防止 sql 注入

MyBatis 的 <bind></bind> 标签本身不是防 SQL 注入的机制,它不直接防止注入,而是用于在 XML 映射文件中预先定义一个变量(绑定表达式结果)供后续 SQL 使用。它的安全性完全取决于你绑定的内容是否来自用户输入、以及是否用了 #{} 还是 ${}。

换句话说:
✅ <bind></bind> 配合 #{} 可以安全使用;
❌ <bind></bind> 配合 ${} 仍会引入 SQL 注入风险。


一、<bind></bind> 的作用和基本用法

<bind></bind> 标签把 OGNL 表达式的结果绑定为一个局部变量,可在同一条 SQL 中多次引用,常用于简化重复逻辑或预处理参数(比如拼接 like 模糊查询通配符)。

示例(安全写法):

<select id="findUsersByName" resulttype="User"><bind name="pattern" value="'%' + username + '%'"></bind>
  SELECT * FROM user WHERE username LIKE #{pattern}
</select>
  • value="'%' + username + '%'" 是 OGNL 表达式,运行在 MyBatis 解析阶段(Java 层),不是 SQL 拼接;
  • #{pattern} 是参数化占位,最终走 PreparedStatement 预编译 → ✅ 安全。

执行时等效于:

Java Maven Code Review
Java Maven Code Review

审查Java Maven项目(ZIP压缩包或GitLab仓库URL),检查代码规范、命名、模块边界、可维护性问题以及重复代码。

下载
SELECT * FROM user WHERE username LIKE ?
-- 参数值为 "%张三%"

二、为什么 <bind></bind> 不等于“防注入”,关键看怎么用

写法 是否安全 原因
<bind name="col" value="columnName"></bind> ORDER BY ${col} ❌ 危险 ${col} 直接字符串替换,若 columnName 来自用户(如前端传 id; DROP TABLE user--),就会执行恶意 SQL
<bind name="col" value="'id'"></bind> ORDER BY ${col} ✅ 安全(仅限固定值) value 是硬编码字符串,无外部输入,但这种写法失去动态意义
<bind name="pattern" value="'%' + keyword + '%'"></bind> WHERE name LIKE #{pattern} ✅ 安全 keyword 是方法参数,经 #{} 绑定,全程预编译

⚠️ 注意:<bind></bind> 中的 value 表达式如果引用了用户可控参数(如 username、sortField),而后续又用 ${} 引用该变量,就等于绕过 #{} 防护 → 注入照旧发生。


三、常见误用场景与正确替代方案

场景1:模糊查询(like)想加 %,但不敢用 #{} 直接拼

  • ❌ 错误尝试(以为 bind 能“兜底”):
    <bind name="likeVal" value="'%' + username + '%'"></bind>
    WHERE username LIKE '${likeVal}' <!-- 用 ${} → 注入! -->
  • ✅ 正确做法(坚持 #{}):
    <bind name="pattern" value="'%' + username + '%'"></bind>
    WHERE username LIKE #{pattern}

场景2:动态排序字段(order by)

  • ❌ 危险写法(不可信字段直插):
    <bind name="sortBy" value="sortField"></bind>
    ORDER BY ${sortBy}
  • ✅ 安全做法(白名单校验 + #{} 不适用,只能 ${},但必须限制输入):
    <!-- Java 层先校验 sortField 是否在 ["id", "username", "create_time"] 中 -->
    <bind name="safeSort" value='@org.apache.commons.lang3.StringUtils@defaultString(sortField, "id")'></bind><!-- 但仍需配合 Java 层白名单判断,不能只靠 bind -->
    ORDER BY ${safeSort}

? 关键原则:<bind></bind> 是“变量声明工具”,不是“安全过滤器”。防注入的唯一可靠路径,是所有用户输入都走 #{};只有极少数受控场景(如排序字段、表名、列名)才允许 ${},且必须配合 Java 层白名单校验。


四、总结:如何让 <bind></bind> 真正“助力”安全

  • 所有含用户输入的绑定值,后续一律用 #{变量名},绝不使用 ${变量名};
  • <bind></bind> 中的 OGNL 表达式避免调用危险方法(如 java.lang.Runtime.exec —— 实际会被 MyBatis 默认禁用,但需知其边界);
  • 复杂场景(如 like + order by + in)优先用 MyBatis 原生动态标签(<if></if>、<foreach></foreach>、<choose></choose>)配合 #{},比手动 bind 更清晰可控;
  • 若必须动态列名/表名,<bind></bind> 可辅助做前置转换,但校验逻辑必须落在 Java 层(如 Enum.valueOf() 或 Set.contains())。

安全不靠语法糖,靠设计意识。<bind></bind> 很轻巧,用对了省事,用错了就是隐形漏洞。

相关文章

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

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

下载

相关标签:

java

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系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

4083

8

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

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

2023.10.27

871

4

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

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

2024.02.23

1069

5

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

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

2024.03.06

5961

10

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

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

2024.03.06

2863

4

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

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

2024.04.07

5940

11

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

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

2024.04.29

7921

6

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

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

2024.04.29

1070

5

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

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

2024.04.29

932

5

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习