sql注入拦截需在网关层严格按顺序执行验签、递归解析json、关键词扫描等步骤,且必须支持规则热更新。

网关层做SQL注入拦截,不是“开个WAF开关就能防住”,而是必须让规则真正看到请求里带SQL特征的那部分数据——否则配置再全也形同虚设。
Spring Cloud Gateway 必须先验签再扫描 body
常见错误是把 SQLInjectionFilter 放在签名校验之前。攻击者发一个伪造的 appKey,直接触发检测逻辑,既绕过身份约束,又可能因 JSON 解析或正则匹配耗尽线程资源。
- 验签顺序必须是:从
exchange.getRequest().getHeaders()或getQueryParams()提取appKey→ 查配置中心拿到对应appSecret→ 拼接timestamp和nonce(字典序)→ 校验签名 -
timestamp与网关当前时间差 >300000ms(5 分钟)即拒 -
nonce需 Redis 去重,5 分钟内重复即拒 - 只有验签通过,才调用
exchange.getRequest().getBody()读取Flux<databuffer></databuffer>,避免body.asString().block()阻塞式读取
JSON body 必须递归遍历所有字符串字段
网关默认不解析 JSON 深层结构。JsonNode.toString() 或 parseObject(requestBody) 只取顶层字段,像 {"filter": {"name": "admin' OR 1=1--"}} 这种会完全漏掉。
- 用
ObjectMapper.readTree()加载为JsonNode,再递归调用findValuesAsText(".*"),或手动遍历所有JsonNodeType.STRING节点 - 对每个字符串值做关键词扫描:
'、"、;、--、#、UNION、SELECT、EXEC(忽略大小写) - 禁用全文
toString()后正则匹配——它会把{、"、:等 JSON 结构符一起吞进去,误报率高 - 注意:gRPC gateway 将 JSON 转 protobuf 后透传,若网关未解析原始 JSON,
UNION SELECT会直接穿过
Nginx 网关需显式启用 ModSecurity 并配置 SecRequestBodyAccess On
if ($args ~* union) 这类规则对 POST + JSON 完全无效,因为 $args 只含 query string,不包含请求体。
- 必须启用
modsecurity模块,并在具体location块中配置SecRequestBodyAccess On(不能放在http或server块顶层,Nginx 会报错) -
SecResponseBodyAccess Off必须关闭,避免响应体误判干扰 - URL 编码至少解一次:
%27→',否则%27OR%201%3D1直接放行 - 纯 Nginx 不读 body,若不用 ModSecurity,只能靠
map $args打标 +if ($sql_flag)拦截 query 参数,POST body 无法覆盖
东西向流量必须用 Envoy Sidecar,不能依赖边缘网关
服务间调用(如 user-service → order-service)根本不会经过 Spring Cloud Gateway 或 Kong 这类边缘网关,只走 Pod 内部网络。
- Envoy Sidecar 是唯一能拦截所有进出 Pod 的 L7 流量的组件
- 必须在
http_connection_manager中为路由显式配置per_route_config+ext_authz过滤器 - 设置
with_request_body: { max_request_bytes: 1048576 },否则拿不到完整 payload - 推荐将可疑请求转发给独立 SQL 解析服务(如基于
libinjection的轻量级解析器),而非在 Envoy 内做正则匹配
最常被忽略的一点:规则热更新能力。所有拦截逻辑都得支持运行时开关,否则上线新规则就得重启网关,而真实攻击往往发生在深夜或节假日——你没法靠“重启”来防守。











