API网关必须在最前端拦截SQL注入,因其是所有HTTP请求的必经入口,可统一校验URL、查询参数、表单、JSON、路径变量及Header/Cookie中的恶意载荷,而业务层防护对绕过App的直接调用完全失效。
API网关不是“能防SQL注入”,而是“必须拦在最前面”——因为所有请求必经它转发,而业务服务层的
或 ORM 校验,对绕过 App 直接调用接口的攻击者完全无效。
为什么网关层拦截不可替代
客户端发的每个 HTTP 请求,无论来自 App、Postman 还是 curl,都得先过网关。这意味着:
攻击者根本不需要破解 App,只要抓包改个
就能试探后端是否拼 SQL
后端即使用了
的
,也挡不住动态 SQL 场景(比如
)或遗留报表模块硬拼字符串
网关可统一管控所有微服务,避免某个服务漏配校验导致整条链路失守
对
这类明文参数,网关能在毫秒级拒绝,不消耗业务服务 CPU 和数据库连接
哪些参数位置必须校验
网关默认只看 URL 路径和查询参数(
),但真实攻击常藏在别处:
请求体:需显式调用
解析,否则
会被直接透传
请求体:必须用
异步读取并解析为
,再递归遍历所有字符串字段;否则
完全看不见
路径参数(如
):需从
提取,不能只扫 query
Header 和 Cookie:虽然少见,但
也是有效攻击面,需按需开启扫描
校验规则怎么写才不误杀也不漏杀
关键词黑名单(如匹配
)极易被大小写、空格、注释绕过,实际应组合三层判断:
防SQL注入的php类库
防SQL注入的php类库
下载
基础特征:用
,
防止匹配到
,
忽略大小写
可疑结构:匹配
、
、
,注意正则中括号要转义
上下文过滤:排除白名单字段名,如参数名为
且值为
或
,不应触发拦截
编码兼容:必须先做一次 URL 解码(
),否则
直接放行;Unicode 编码(
)属于高阶需求,需额外加解码逻辑
严格模式下如何配置未知参数处理
启用「拒绝未知参数」策略(strict mode)是性价比最高的第一道过滤,但必须明确边界:
全局开关不推荐:用路由粒度控制,比如
启用,
关闭(后台 SQL 调试接口天然需要传原始 SQL)
参数名校验要区分大小写:配置
就不该放过
或
,否则可能绕过白名单
JSON Body 的字段名校验需配合 Schema:仅靠 key 名匹配不够,要解析 JSON 后检查
字段值是否为字符串类型,避免把
误判为 SQL 片段
禁用
或
的自动透传,这类请求体若含恶意 payload,网关默认不解析也不校验
真正容易被忽略的是:网关规则生效的前提是「它确实看到了数据」——如果没开请求体解析、没配 JSON 解码器、没处理 URL 编码,那再强的正则也等于没写。
PreparedStatementid=1%20OR%201%3D1MyBatis#{}${sortField}GET /search?q=admin'request.getQueryParams()application/x-www-form-urlencodedServerWebExchange.getFormData()id=1'--application/jsonFluxJsonNode{"filter": "name = 'admin' OR 1=1"}/user/{id}ServerWebExchange.getAttribute("org.springframework.cloud.gateway.support.ServerWebExchangeUtils.uriTemplateVariables")Cookie: session=' OR 1=1--UNION SELECT(?i)\b(SELECT|UNION|INSERT|UPDATE|DELETE|DROP|EXEC)\b\bSELECTED(?i);\s*--'\s*OR\s*'1'\s*=\s*'1'sleep\(\d+\)sql_type"count""detail"%27 → '%27OR%201%3D1%u0027/api/**/admin/**userIduseridUSERIDfilter{"filter": {"type": "like"}}Content-Type: text/plainapplication/octet-stream