WallFilter 非“开即生效”,需显式配置严格匹配的db-type(如mysql)、启用对应校验开关(如multi-statement-allow、comment-allow),并升级至1.2.38+以支持新语法,否则静默失效。

Druid 的 WallFilter 不是“开了就防住”,配置错一个参数,它就完全不生效,甚至静默跳过校验。
WallFilter 没加载?先确认 db-type 是否显式指定且匹配
WallFilter 必须知道你连的是哪种数据库,才能加载对应的 WallProvider(如 MySqlWallProvider)做语义分析。Spring Boot 下仅配 druid.filters=wall 是不够的。
-
db-type必须显式指定,且值严格匹配 JDBC URL 对应类型:mysql(不是mysql5或mysql8)、postgresql(写成postgres会失败)、oracle - Druid 1.2.38+ 版本起,
db-type不再自动推断;缺失或写错,直接降级为无规则校验 - 启动时搜日志里有没有
WallFilter init with dbType: mysql—— 没这句说明根本没加载,后续所有开关都无效
SQL 报错 “sql injection violation, multi-statement not allow” 怎么办
这是 WallFilter 默认拦截分号分隔的多语句(如 SELECT 1; DELETE FROM users;),常见于 MyBatis 批量操作或 JDBC 层拼接场景。
- 临时放开:在
druid.wall.config下设multi-statement-allow: true - 但注意:
multi-statement-allow: true只绕过语法限制,不跳过注入检测;真正安全的做法是改用addBatch()+executeBatch() - 若业务真需多语句,要确认是否由 MyBatis 的
${}或 JDBCStatement主动拼接导致 —— 这本身已是高危行为
DELETE/UPDATE 无 WHERE 却不报错?检查对应校验开关是否启用
WallFilter 默认不拦截 DELETE FROM users 或 UPDATE orders SET status = 1,除非你主动开启语义级检查。
-
delete-where-none-check: true才拦截无WHERE的DELETE -
update-where-none-check: true才拦截无WHERE的UPDATE -
delete-where-alway-true-check: true和update-where-alway-true-check: true才拦截恒真条件(如WHERE 1=1、OR '' = '') - 这些字段必须写在
druid.wall.config下级,YAML 缩进错位会导致解析失败、被完全忽略
注释、CTE、窗口函数报 syntax error?Parser 版本和 strictSyntaxCheck 得配合调
旧版 Druid(如 1.2.20)的 SQL Parser 无法识别 MySQL 8.0+ 的 CTE、窗口函数等语法,直接抛 syntax error,整条 SQL 被跳过校验。
- 首选方案:升级 Druid 至
1.2.38+,内置 Parser 已支持主流新语法 - 临时应对:设
strictSyntaxCheck: false—— 注意这只是关掉语法校验,不影响注入规则生效 - 别忘了开
comment-allow: true,否则带--或/* */的合法注释也会被拦
最常被忽略的一点:WallFilter 只对原始 SQL 字符串做 AST 分析,一旦你在代码里用 ${} 或字符串拼接构造 SQL,它看到的就是完整恶意语句;而 #{} 和 PreparedStatement 参数会被剥离,Parser 只看到占位符 —— 这是设计前提,也是你必须坚持参数化的根本原因。











