waf默认不拦截sql注入因关键配置未启用:需开启secrequestbodyaccess、后端传递请求体、将规则动作设为“阻断”,并配合owasp crs异常分数机制与nginx map快速兜底,同时正则须覆盖编码、注释、大小写等绕过方式。

WAF能拦SQL注入,但默认配置基本不拦——不是规则不存在,而是关键开关没开、请求体没传、动作设成“记录”而非“阻断”。
SecRequestBodyAccess 必须显式开启
SQL注入大量藏在 POST body 里(比如 JSON 登录请求、表单提交),而 Nginx 默认不把原始请求体传给 ModSecurity。不开这个,REQUEST_BODY 和 ARGS_POST 规则永远匹配不到内容。
-
SecRequestBodyAccess On要写在modsecurity.conf全局配置里,不能只放在location块内 - 后端是 PHP-FPM:在
location ~ \.php$块中加fastcgi_pass_request_body on; - 后端是
proxy_pass(如 Node.js/Java):对应location加proxy_pass_request_body on; - 漏掉任一环节,
REQUEST-942-APPLICATION-ATTACK-SQLI.conf就等于摆设
OWASP CRS 的 SQLI 规则不能直接开全
CRS 3.x/4.x 的 SQLI 规则很强,但默认策略偏保守:只记录不拦截,且对 multipart/form-data 解析支持弱,上传接口带参数时极易漏检。
- 必须手动启用异常分数阻断逻辑,例如:
SecRule TX:ANOMALY_SCORE "@gt 5" "id:1000,deny,status:403,msg:'SQLi detected'" - 首次上线务必先用
SecRuleEngine DetectionOnly运行 3–5 天,看modsec_audit.log里误报——order by id、limit 10都可能被标为高危 - 若业务大量用
LIKE '%xxx%',需临时禁用942100(LIKE 检测规则),否则正常搜索全 403
加一层 Nginx map 快速兜底防绕过
ModSecurity 启动慢、单请求多耗 5–15ms,且对大小写变换、十六进制编码、注释符绕过等响应滞后。用 map 提前拦截高频攻击特征,成本几乎为零。
- 在
http块定义:map $args $sql_flag { ~*[\"'`;\(\)\/\*%00] 1; ~*(select|union|insert|update|delete|drop|sleep|benchmark) 1; default 0; } - 在
server或location中:if ($sql_flag = 1) { return 403; } - 注意:
map只能匹配$args(GET 参数),POST body 需配合前面的SecRequestBodyAccess才完整 - 这条规则挡不住
SEL/**/ECT或%73elect,但它能快速筛掉 80% 的扫描器原始 payload
正则规则必须覆盖空格、注释、编码三类绕过
只写 union\s+select 是拦不住真实攻击的。攻击者会用 UnIoN/**/SeLeCt、union%09select、union%20select 等方式绕过。
- 真正有效的正则应为:
(?i)union[\s%09%0a%0b%0c%0d\xa0](?:/\*\*\/|--+|#)?[\s%09%0a%0b%0c%0d\xa0]select - 必须加
\b边界符,并启用 URL/十六进制解码预处理,否则admin%27%20or%20%271%27%3d%271就会漏判 - 避免用
.*匹配中间内容,性能差还容易误杀;改用[^&\n\r]{0,50}限制长度 - 只列单个词(如
select)必然误伤,必须抓语义组合——比如select.*from、union.*select、sleep\(
最易被忽略的是:WAF日志里出现拦截记录 ≠ 请求真被阻断。一定要用真实请求测试,比如 curl -X POST -H "Content-Type: application/json" --data '{"username":"admin' OR 1=1 --"}' http://test.com/login,观察是否返回 403 并在日志中查到明确匹配的 rule_id。











