SQL注入防护必须前移至网关层,仅靠应用层校验易失效;Apache ShenYu可通过WAF插件+自定义正则规则拦截,需按路径分组配置、避免误杀,并关注规则同步与性能影响。

SQL注入防护不能只靠应用层校验
很多团队在代码里加了 PreparedStatement、过滤 ' 和 --,就认为 SQL 注入问题已解决。但真实生产环境里,第三方 SDK、遗留模块、动态拼接的报表查询、甚至 ORM 框架的 createSQLQuery 或原生 SQL 注解,都可能绕过这些校验。尤其在分布式系统中,服务间调用链长、数据来源多(如网关透传参数、MQ 消息反序列化后拼 SQL),单点防御极易失效。
必须把防护前移到流量入口,让所有 HTTP 请求在到达业务服务前就被统一检测和阻断。
用 Apache ShenYu 网关做 SQL 注入规则拦截
ShenYu 本身不内置 SQL 注入识别引擎,但可通过其 WAF 插件 + 自定义规则实现精准拦截。关键不是“全量关键词匹配”,而是结合上下文做轻量级语义判断:
- 对
GET请求的query参数、POST的application/x-www-form-urlencoded和application/jsonbody 中的字符串字段,提取所有疑似 SQL 片段(如含SELECT、UNION SELECT、EXEC、xp_cmdshell、sleep(、benchmark() - 排除白名单场景:如参数名是
sql但值为固定枚举("count"、"detail"),或出现在 Swagger 文档描述字段中 - 使用正则增强识别:匹配
[s;]+(union|select|insert|update|delete|drop|create|alter)[s(]+,注意大小写不敏感且支持空格/换行/注释干扰 - 规则配置路径在 ShenYu Admin 控制台 →
插件管理 → WAF → 规则编辑,启用后需重启shenyu-bootstrap实例
示例规则片段(JSON 格式):
{
"name": "block-sql-injection",
"enabled": true,
"match": "body.*|query.*",
"pattern": "(?i)(\b(SELECT|UNION|INSERT|UPDATE|DELETE|DROP|CREATE|ALTER)\b|\b(xp_cmdshell|sleep|benchmark)\b|;\s*--)",
"action": "reject",
"message": "SQL injection attempt detected"
}
避免误杀:区分管理接口与业务接口
后台管理类接口(如 /admin/sql/explain、/debug/query)天然需要传 SQL,若统一拦截会直接导致功能不可用。必须按路径做规则分组:
- 全局默认规则:拦截所有
/api/**、/v1/**等业务路径 - 独立白名单规则:针对
/admin/**、/ops/**路径,关闭 WAF 插件,改用 IP 白名单 + JWT 权限校验(通过auth插件控制) - 不要用“开关式”配置——即不在 ShenYu Admin 里手动启停插件,而应通过路由粒度绑定:每个路由可单独指定是否启用
waf插件 - 测试时务必用真实报文验证:比如
{"name": "test'; DROP TABLE users--"}应被拦截,但{"sql": "count"}不应触发
分布式部署下规则同步与性能影响
ShenYu 集群节点间不共享内存,WAF 规则必须从 MySQL 或 ZooKeeper 加载。若用 MySQL 存储规则:
- 确保
shenyu-admin更新规则后,所有shenyu-bootstrap节点能在 5 秒内拉取到变更(检查shenyu.sync.database.props.pollInterval配置,默认 3000ms) - 正则匹配本身有 CPU 开销,高并发下可能成为瓶颈。建议对 JSON body 做采样匹配:仅检查前 2KB 内容,避免解析超大文件上传请求
- 禁用
WAF插件的日志全量打印(shenyu.plugin.waf.log.enable=false),否则磁盘 I/O 会拖慢整个网关 - 线上压测发现:开启 WAF 后 P99 延迟增加约 8~12ms,但比被注入后数据库锁表、连接池耗尽导致的雪崩代价小得多
真正容易被忽略的是规则更新后的灰度验证——别直接全量推送,先选一个网关节点打标(如加 JVM 参数 -Dshenyu.instance.id=gray-01),观察日志里的 WafPlugin: match=true, rule=block-sql-injection 是否符合预期。

















