diff --git a/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf b/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf index d22167ad8..3924c6615 100644 --- a/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf +++ b/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf @@ -319,6 +319,35 @@ SecRule REQUEST_METHOD "@rx ^POST$" \ setvar:'tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/INVALID_HREQ-%{MATCHED_VAR_NAME}=%{MATCHED_VAR}'" +# +# As per RFC7230 3.3.2: A sender MUST NOT send a Content-Length +# header field in any message that contains a Transfer-Encoding header +# field. +# +# Related to 920170, 920171 and 920180. +# +SecRule &REQUEST_HEADERS:Transfer-Encoding "!@eq 0" \ + "id:920181,\ + phase:2,\ + block,\ + t:none,\ + msg:'Content-Length and Transfer-Encoding headers present.',\ + tag:'application-multi',\ + tag:'language-multi',\ + tag:'platform-multi',\ + tag:'attack-protocol',\ + tag:'OWASP_CRS/PROTOCOL_VIOLATION/INVALID_HREQ',\ + tag:'CAPEC-272',\ + ver:'OWASP_CRS/3.1.0',\ + severity:'CRITICAL',\ + chain" + SecRule &REQUEST_HEADERS:Content-Length "!@eq 0" \ + "t:none,\ + setvar:'tx.msg=%{rule.msg}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ + setvar:'tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/INVALID_HREQ-%{MATCHED_VAR_NAME}=%{MATCHED_VAR}'" + + # # Range Header Checks # diff --git a/util/regression-tests/tests/REQUEST-920-PROTOCOL-ENFORCEMENT/920181.yaml b/util/regression-tests/tests/REQUEST-920-PROTOCOL-ENFORCEMENT/920181.yaml new file mode 100755 index 000000000..5a4bce83a --- /dev/null +++ b/util/regression-tests/tests/REQUEST-920-PROTOCOL-ENFORCEMENT/920181.yaml @@ -0,0 +1,35 @@ +--- + meta: + author: "fgsch" + enabled: true + name: "920181.yaml" + description: "Description" + tests: + - + test_title: 920181-1 + stages: + - + stage: + input: + dest_addr: "127.0.0.1" + port: 80 + method: "POST" + uri: "/" + headers: + Host: "localhost" + Accept: "*/*" + Content-Length: 7 + Content-Type: "application/x-www-form-urlencoded" + Transfer-Encoding: "chunked" + User-Agent: "ModSecurity CRS 3 Tests" + data: + - "7" + - "foo=bar" + - "0" + - "" + - "" + stop_magic: true + output: + # Apache unsets the Content-Length header if + # Transfer-Encoding is found! + no_log_contains: id "920181"