报错是这么冒出来的。站点接入云 WAF 后,后台批量提交的 JSON 接口被拦,返回 403 并带一页拦截提示,同一个接口用表单提交却能过,日志里规则命中的是 SQL 注入。
中间走过弯路,把「接口里有 base64 字段,随机字符串命中了命令注入的正则」当成主因,改完现象没变。
真正麻烦的地方在于,几个原因的现象几乎一样。请求体是 JSON,WAF 按表单解析拿不到参数,误把整段 JSON 当成注入特征。少数情况下是Content-Type 写成 text/plain,WAF 走了另一套宽松解析规则。
还有一种情况,规则是全局生效的,没有按 URL 配置例外。
先在 WAF 日志里确认命中的规则 ID
aliyun waf DescribeLogs --Query '{"host":"www.example.com","status":"403"}'
随后用原始报文复现被拦的请求
curl -s -o /dev/null -w '%{http_code}' -X POST -H 'Content-Type: application/json' -d '{"sql":"select 1"}' https://www.example.com/api/batch
给该 URL 加规则例外
aliyun waf ModifyProtectionRule --RuleId 1001 --Action bypass --Urls '/api/batch'
等前面都确认过,再确认放行后请求正常通过
curl -sI -X POST -H 'Content-Type: application/json' -d '{}' https://www.example.com/api/batch | head -1
别只看报错消失,验证要多做一步。该接口返回 200 且 WAF 日志里不再出现拦截记录,其他路径的告警仍然照常产生。
补一句。按 URL 放行比关掉整条规则安全得多;上线前把 JSON 接口用真实报文在 WAF 测试模式跑一遍,能省掉大量误拦投诉。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。
