如何编写ModSecurity/Coraza规则拦截含指定JSON值的POST请求?
解决Coraza/ModSecurity规则无法匹配POST JSON请求体的问题
核心原因
日志显示arg="",说明规则匹配时REQUEST_BODY变量为空,本质是未启用请求体读取功能,或JSON请求体被解析后原始REQUEST_BODY未被保留。
解决方案
1. 启用请求体访问
首先确保配置中开启请求体读取,这是规则能获取REQUEST_BODY的前提:
SecRequestBodyAccess On
缺少这条配置时,Coraza/ModSecurity不会读取请求体内容,REQUEST_BODY自然为空。
2. 方式一:直接匹配REQUEST_BODY(需保留原始请求体)
若要继续使用REQUEST_BODY匹配,需确保JSON请求体的原始内容被保留。部分场景下,JSON解析后REQUEST_BODY会被清空,可添加以下配置:
SecSaveUploadedFiles On SecRequestBodyLimit 131072 # 根据实际请求体大小调整,默认128KB
然后调整规则(可使用单引号包裹匹配内容避免转义):
# 转义写法 SecRule REQUEST_BODY "@contains {\"foo\":\"bar\"}" "id:1001,phase:2,deny,log" # 单引号简化写法 SecRule REQUEST_BODY "@contains 'foo\":\"bar'" "id:1001,phase:2,deny,log"
3. 方式二:使用ARGS_JSON集合匹配(更推荐)
针对JSON请求,Coraza/ModSecurity会自动解析JSON到ARGS_JSON变量集合,直接匹配键值对更精准,还能避免JSON格式(如空格、换行)导致的匹配失败:
# 匹配foo键的值为bar的请求 SecRule ARGS_JSON:foo "@streq bar" "id:1001,phase:2,deny,log"
4. 验证配置
修改配置后重启Coraza/ModSecurity服务,再用原curl命令测试:
curl -v -H "Content-Type: application/json" -X POST -d '{"foo":"bar"}' http://localhost
此时请求应被拦截,日志会显示规则匹配成功。
内容的提问来源于stack exchange,提问作者user2233706
相关产品推荐
相关产品推荐

