libModSecurity:允许使用Content-Type进行GET:application / json

时间:2018-03-07 12:43:42

标签: json ghost-blog mod-security

我正在设置一个(自托管的)ghost博客,在nginx后面运行。我最近使用OWASP CRS v3规则集添加了ModSecurity v3(也就是libModSecurity)WAF,但是我在解决一些误报方面遇到了麻烦。

我的问题与this question非常相似,但建议的解决方案对我不起作用。

触发的规则是:

SecRule REQBODY_ERROR "!@eq 0" \
"id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2"

我认为问题的原因是ghost(正确或错误)为ajax Content-Type: application/json请求指定了GET标头,以便将一些配置数据下载为Json。 请求被阻止,因为此Content-Type标头触发请求正文的JSON解析器:

SecRule REQUEST_HEADERS:Content-Type "application/json" \
     "id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON"

但是,这是一个没有请求体的GET请求,因此JSON解析器会抱怨JSON parsing error: parse error: premature EOF ...即没有要解析的Json。

尝试阅读无数指南后,来自ModSecurity documentationBarry Pollard许多有用的答案(例如herehere和{ {3}}),我试图编写一个特定于我的触发器场景的“白名单”规则(而不是全局禁用触发的规则)。 因此,我尝试使用以下链式规则将请求体排除在解析之外:仅针对GET个请求,针对以/ghost/开头的URI以及为Content-Type指定application/json的URI。 ..

SecRule REQUEST_URI "^/ghost/" "phase:1,id:1200,t:none,t:urlDecode,t:lowercase,t:normalizePath,pass,ctl:requestBodyAccess=Off,chain"
    SecRule REQUEST_METHOD "@streq get" "t:none,t:lowercase,chain"
        SecRule REQUEST_HEADERS:Content-Type "application/json" "t:none,t:lowercase"

令我失望的是,这不起作用 - 我的规则在记录规则200002之前的审核日志中。换句话说,ctl:requestBodyAccess=Off似乎不会阻止JSON解析器被触发。以下是失败事务的审计日志的相关位:

ModSecurity: Warning. Matched "Operator `Rx' with parameter `application/json' against variable `REQUEST_HEADERS:content-type' (Value: `application/json; charset=UTF-8' ) [file "/etc/nginx/modsec/modsecurity.conf"] [line "8"] [id "1200"] [rev ""] [msg ""] [data ""] [severity "0"] [ver ""] [maturity "0"] [accuracy "0"] [hostname "xxx.xxx.xxx.xxx"] [uri "/ghost/api/v0.1/configuration/"] [unique_id "152042340176.931426"] [ref "o0,7v4,30t:urlDecode,t:lowercase,t:normalizePathv0,3t:lowercaseo0,16v416,31t:lowercase"]
ModSecurity: Access denied with code 400 (phase 2). Matched "Operator `Eq' with parameter `0' against variable `REQBODY_ERROR' (Value: `1' ) [file "/etc/nginx/modsec/modsecurity.conf"] [line "51"] [id "200002"] [rev ""] [msg "Failed to parse request body."] [data "JSON parsing error: parse error: premature EOF\x0a"] [severity "2"] [ver ""] [maturity "0"] [accuracy "0"] [hostname "xxx.xxx.xxx.xxx"] [uri "/ghost/api/v0.1/configuration/"] [unique_id "152042340176.931426"] [ref "v561,1"]

FWIW,我也尝试过Barry提出的更简单的规则,用于另一个类似的问题:

SecRule REQUEST_BODY_LENGTH "@eq 0" "phase:1,id:'12345',ctl:requestBodyAccess=Off"

但这也没有什么不同。作为GET,请求标头中没有指定Content-Length,所以也许这就是它失败的原因?

2 个答案:

答案 0 :(得分:0)

作为一种解决方法,我设法使用以下规则压制这种特殊的误报:

SecRule REQUEST_URI "^/ghost/" "phase:1,id:1200,t:none,t:urlDecode,t:lowercase,t:normalizePath,nolog,chain"
    SecRule REQUEST_METHOD "@streq get" "t:none,t:lowercase,chain"
        SecRule REQUEST_HEADERS:Content-Type "application/json" "t:none,t:lowercase, \
           ctl:ruleRemoveById=200002, \
           ctl:ruleRemoveById=920130"

(规则920130基本上是与SpiderLabs规则200002等效的OWASP CRS。)

然而,我需要一个规则来防止Json正文解析器错误导致拒绝这些事务似乎很愚蠢,在这种情况下防止正文解析器被调用肯定会更有效(当我决定时)? / p>

如果有人能解释如何让ctl:requestBodyAccess=Off工作,我将不胜感激!

答案 1 :(得分:0)

你试过这个:

SecRule REQUEST_URI "^/ghost/" "phase:1,id:1200,t:none,t:urlDecode,t:lowercase,t:normalizePath,pass,ctl:requestBodyAccess=Off,chain"
    SecRule REQUEST_METHOD "@streq get" "t:none,t:lowercase,chain"
        SecRule REQUEST_HEADERS:Content-Type "application/json" "t:none,t:lowercase"

你能试试吗?

SecRule REQUEST_URI "^/ghost/" "phase:1,id:1200,t:none,t:urlDecode,t:lowercase,t:normalizePath,pass,chain"
    SecRule REQUEST_METHOD "@streq get" "t:none,t:lowercase,chain"
        SecRule REQUEST_HEADERS:Content-Type "application/json" "t:none,t:lowercase, ctl:requestBodyAccess=Off"

我认为(虽然我看到这个已经有一段时间了!),像Ctrl这样的无中断行动应该在链的末尾,而破坏性的行为(例如通行证)应该在开头。

但是我看了一会儿这么久就错了......