MyBatis中#{}防SQL注入但不防语义污染,LIKE查询需手动转义%_并显式声明ESCAPE;跨库CONCAT不兼容,应按方言切换SQL;QueryWrapper.like需校验空值、长度、trim;ORDER BY等动态列名必须用严格白名单校验。

MyBatis里用#{}是底线,但%_仍会破坏语义
只靠#{}能防注入,但挡不住业务逻辑错乱。比如用户搜“a_b”,你写WHERE name LIKE CONCAT('%', #{name}, '%'),数据库会把下划线当通配符,实际匹配“aXb”“aYb”——这不是注入,是语义污染。
根本矛盾在于:用户输入的%_该当字面量还是通配符?必须由业务决定,不能交给数据库默认解析。
- Java 层拼接前先转义:
userInput.replace("%", "\%").replace("_", "\_").replace("\", "\\"); - SQL 中必须显式声明
ESCAPE '\',否则转义无效 - MySQL 默认允许反斜杠转义,但开启
NO_BACKSLASH_ESCAPES模式后,\%就不认了——得换 ESCAPE 字符,比如ESCAPE '$' - Oracle 要求反斜杠双写:
'\%'才表示字面反斜杠加百分号;PostgreSQL 推荐用ESCAPE '$'避免驱动层解析冲突
CONCAT + #{} 写法在各数据库的兼容性坑
CONCAT('%', #{name}, '%') 看似安全,但跨库时语法和行为不一致。MySQL 支持,Oracle 和 PostgreSQL 不认 CONCAT 二元函数(Oracle 需 ||,PostgreSQL 可用但对 null 敏感)。
更稳的方式是按数据库方言切换 SQL 片段,或统一用 JDBC 参数化后由 Java 拼好完整 pattern。
立即学习“Java免费学习笔记(深入)”;
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- MySQL:
WHERE name LIKE CONCAT('%', #{name}, '%') ESCAPE '\' - Oracle:
WHERE name LIKE '%' || #{name} || '%' ESCAPE '\' - PostgreSQL:
WHERE name LIKE '%' || #{name} || '%' ESCAPE '$'(配合连接参数standard_conforming_strings=on) - SQL Server:
WHERE name LIKE '%' + #{name} + '%' ESCAPE ''
QueryWrapper.like() 看似省事,但空值和长度没校验照样出事
queryWrapper.like("name", username) 内部确实用 #{},不会注入,但它不处理 username 是 null、空字符串、超长串或含恶意 payload 的情况。
攻击者传个 10MB 的 username,数据库 LIKE 全表扫描+日志打满,服务直接卡死——这不算注入,但属于拒绝服务攻击。
- 务必前置校验:
if (!StringUtils.isNotBlank(username) || username.length() > 50) throw new IllegalArgumentException(); - 避免链式调用中混入未校验字段:
.like("name", username).or().eq("status", userStatus)—— 若userStatus来自前端且没白名单,or()后的条件就可能被利用 -
like方法不自动 trim,用户输“ admin ”会查不到——要自己username = username.trim()
ORDER BY 动态排序字段必须白名单,${} 无法避免
像 ORDER BY ${sortField} 这种场景,#{} 完全无效,因为数据库不允许参数化列名。此时唯一靠谱的做法是硬编码白名单,而不是正则过滤。
写 sortField.matches("[a-zA-Z_]+") 看似干净,实则危险:它放行 id, (SELECT 1) 这类子查询注入,也拦不住 create_time DESC, (SELECT ...) 这种组合攻击。
- 定义严格白名单:
Set.of("name", "create_time", "status") - 校验必须在 DAO 层入口做,不能只在 Controller 或 Service 里一次判断就完事
- 白名单校验失败应直接返回 400,不要 fallback 到默认字段——fallback 本身可能被探测利用

















