网关层SQL注入拦截需严格遵循数据处理顺序与深度解析:必须先验签再读body,JSON需递归提取字符串值检测关键词,Nginx须启用SecRequestBodyAccess并解码,东西向流量须用Envoy Sidecar防护,且网关无法拦截业务层拼接漏洞。

网关层做SQL注入拦截,不是加个正则开关就能生效——规则必须真正看到请求体里带SQL特征的那部分数据,且顺序不能错、解码不能漏、递归不能浅。
Spring Cloud Gateway 必须先验签再读 body
常见错误是把 SqlInjectionFilter 放在签名校验之前。攻击者发一个伪造 appKey,直接触发 JSON 解析和关键词扫描,既绕过身份约束,又可能因正则匹配或大字段耗尽线程资源。
- 验签必须从
exchange.getRequest().getHeaders()或getQueryParams()提取appKey,查配置中心拿到对应appSecret - 签名原文按字典序拼接
timestamp和nonce,时间差 > 300000ms(5 分钟)即拒 -
nonce需 Redis 去重,5 分钟内重复即拒 - 只有验签通过,才调用
exchange.getRequest().getBody()获取Flux<DataBuffer>,禁用body.asString().block()
JSON body 必须递归提取字符串值,不能 toString() 全文扫
JsonNode.toString() 或 parseObject(requestBody) 只取顶层字段,像 {"filter": {"name": "admin' OR 1=1--"}} 这种会完全漏掉。结构符 {、:、" 被一起纳入扫描,还会导致误报(比如把 user_name 当成 SQL 关键字)。
- 用
ObjectMapper.readTree(byte[])加载为JsonNode - 调用
jsonNode.findValuesAsText(".*"),或手动遍历所有JsonNodeType.STRING节点 - 对每个字符串值单独检测:
'、;、--、#、UNION、SELECT、EXEC(忽略大小写) - 禁用全文
toString()+ 正则匹配——它不区分结构与内容
Nginx 网关必须启用 SecRequestBodyAccess 并解码一次
纯 Nginx 的 $args 和 $request_uri 不含 POST body,if ($args ~* union) { return 403; } 对 JSON 请求完全无效。要覆盖 body,必须显式启用解析模块。
立即学习“Java免费学习笔记(深入)”;
- 启用 ModSecurity,并在具体
location块中配置SecRequestBodyAccess On(不能放http或server块顶层,Nginx 会报错) - 设置
client_body_buffer_size 1m,防大文件耗尽内存 - 确保至少解一层 URL 编码:
%27→',否则%27OR%201%3D1直接放行 - 攻击者常用双重编码(如
%2555NION),需配合rewrite ^(.*)$ $1 break;+set $args重写参数,让规则作用于最终解码结果
东西向流量必须用 Envoy Sidecar,不能依赖边缘网关
服务间调用(如 user-service → order-service)根本不会经过 Spring Cloud Gateway 或 Kong,只走 Pod 内部网络。边缘网关对这类流量完全不可见。
- Envoy Sidecar 能拦截所有进出 Pod 的 L7 流量,支持完整 JSON/gRPC 载荷解析
- 可通过
ext_authz过滤器将可疑请求转发给独立 SQL 解析服务(如基于libinjection的轻量引擎) - 东西向防护必须与南北向规则保持一致的解码层级和关键词集,否则形成防御缺口
- 若用 OPA 或 WASM 扩展,注意其 JSON 解析能力是否支持深层嵌套(如
{"query":{"filter":{"$where":"this.x==1"}}})
最常被忽略的是:网关看到的永远是 HTTP 层的原始字节,不是业务层拼出的 SQL。它拦不住 ${} 拼接、String.format 硬编码、或 MyBatis 动态 SQL 中的语义漏洞——那些得靠 JDBC 层的 PreparedStatement 和 Druid WallFilter 牢牢兜底。


















