微服务架构下SQL注入防护必须在网关层强制拦截,因攻击者可绕过所有服务内PreparedStatement直接curl网关接口;需覆盖南北向与东西向流量,依赖Envoy Sidecar或Spring Cloud Gateway等组件对URL、查询参数、JSON/Form请求体进行按需解析与快速拒绝,且规则须支持热更新与多协议深度解析。

微服务架构下,SQL注入防护不是“可选”,而是所有流量必经路径上的强制关卡——因为攻击者根本不会调用你的 UserServiceImpl,而是直接 curl 网关暴露的 /api/v1/users 接口,绕过所有服务内层的 PreparedStatement 和 ORM 自动转义。
为什么每个微服务自己加 PreparedStatement 不够用
单个服务里用 PreparedStatement 或 MyBatis 的 #{} 确实能拦住内部逻辑漏洞,但前提是请求真进了那个服务。现实中,攻击流量往往在网关层就被转发、重写甚至透传,比如:
- 网关做了 path rewrite(如
/user→/users-service/user),但没校验 query string 里的id=1' OR '1'='1 - 前端直连某服务的 Kubernetes Service IP(绕过网关),而该服务未开启 JWT 校验或只校验 header、忽略 body
- gRPC gateway 把 JSON 请求转成 protobuf 后发给后端,但网关本身没解析 body,
union select就藏在字段值里一路透传
网关层拦截必须覆盖东西向和南北向流量
Envoy Sidecar 能比边缘 WAF 更早介入,是因为它部署在 Pod 内,既处理从 Ingress Controller 进来的南北向请求,也处理服务间调用的东西向流量。但要注意:
-
http_connection_manager默认不解析 request body,必须显式配置per_route_config+ext_authz过滤器,并设置with_request_body: { max_request_bytes: 1048576 }才能拿到完整 payload - 若只配正则匹配
args或path,会漏掉 JSON body 里的"username": "admin'--"—— 因为 Nginx 的$args不包含 POST body - JWT 校验必须放在 SQL 检测之前,否则未认证请求可能触发检测服务的资源耗尽(比如恶意构造超大 base64 token)
Spring Cloud Gateway 的 GlobalFilter 容易拖垮性能的三个坑
很多人想在 GlobalFilter 里统一做 SQL 检测,结果压测时 TPS 断崖下跌。关键问题不在逻辑,而在读取方式:
- 对
application/json类型,别用body.asString().block()—— 这会阻塞线程且无法流式处理;改用exchange.getRequest().getBody()返回的Flux<databuffer></databuffer>,配合flatMap拼接再扫描 - 禁止递归遍历
JsonNode树:用jsonNode.toString()后做关键字扫描,比jsonNode.findValuesAsText("username")快 3 倍以上,且避免 OOM - 开关必须可热更新:
gateway.sql-injection.enabled=true配在application.yml,运行时通过@RefreshScope+@Value("${gateway.sql-injection.enabled:true}")控制,误杀时秒级关闭
Nginx 网关只能靠 map + if 拦 query string,POST body 怎么办
Nginx 默认不读取 request body,所以纯 if ($args ~* ...) 只能防 GET。要覆盖 POST/PUT,得额外动作:
- 先用
map $args $sql_flag打标 URI 和 query string,这是零依赖、高性能的第一道筛 - 对 POST body,必须启用第三方模块:要么用
ngx_http_body_filter_module(需编译进 Nginx),要么上ModSecurity并配置 CRS 规则集(但会引入 C++ 依赖和额外延迟) - 别写
if ($request_method = POST) { ... }嵌套判断——Nginx 的if在 location 外无效,且嵌套多层会显著降低吞吐
真正难的不是写规则,而是确认每条流量是否真的被某个组件“看见并解析”了。一个 select 1 可能出现在 header、query、form data、JSON 字段、甚至是 gRPC metadata 里——防护点必须和协议解析深度对齐,而不是靠一层正则硬扛。

















