• caglararli@hotmail.com
  • 05386281520

Modsecurity blocks blocks my legit XHR POST request (403 forbidden)

Çağlar Arlı      -    22 Views

Modsecurity blocks blocks my legit XHR POST request (403 forbidden)

I'm new to modsecurity topic so maybe my question is stupid but...

I have setup modsecurity on my new nginx/1.24.0 server with default set of recommended rules: coreruleset-3.3.0 and since then my POST XHR request is being blocked. This is a basic Laravel/Livewire form.

The headers sent and logged by modsecurity look like:

POST /livewire/update HTTP/2.0
content-type: application/json
origin: https://example.com
referer: https://example.com/en
pragma: no-cache
accept-encoding: gzip, deflate, br
cookie: XSRF-TOKEN=eyJpdiI6IkJVTXpEK01rYTRYVFI1aGxjOE9T...
content-length: 540
accept-language: it-IT,it;q=0.8,en-US;q=0.5,en;q=0.3
te: trailers
accept: */*
cache-control: no-cache
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0
sec-fetch-site: same-origin
sec-fetch-dest: empty
authorization: Basic Y2Z0cmFbjpjmdG9u
host: example.com
sec-fetch-mode: no-cors

and the logs report:

  1. "Content-Length HTTP header is not numeric" - but I for me "540" looks numeric!
ModSecurity: Warning. Matched "Operator `Rx' with parameter `^\d+$' against variable `REQUEST_HEADERS:content-length' (Value: `540' ) 
[file "/etc/nginx/modsec/coreruleset-3.3.0/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf"] 
[line "127"] 
[id "920160"] 
[msg "Content-Length HTTP header is not numeric"] 
[data "540"] 
[severity "2"] 
  1. "Illegal Content-Type header" - how come "application/json" is illegal?
ModSecurity: Warning. Matched "Operator `Rx' with parameter `^[\w/.+-]+(?... against variable `REQUEST_HEADERS:content-type' (Value: `application/json' ) 
[file "/etc/nginx/modsec/coreruleset-3.3.0/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf"] 
[line "915"] 
[id "920470"] 
[rev ""] 
[msg "Illegal Content-Type header"] 
[data "application/json"] 
[severity "2"] 
  1. "Invalid HTTP Request Line" - what is invalid about this: "POST /livewire/update HTTP/2.0"?
ModSecurity: Warning. Matched "Operator `Rx' with parameter `^(?i:(?:[a-... against variable `REQUEST_LINE' (Value: `POST /livewire/update HTTP/2.0' ) 
[file "/etc/nginx/modsec/coreruleset-3.3.0/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf"] 
[line "47"] 
[id "920100"] 
[msg "Invalid HTTP Request Line"] 
[data "POST /livewire/update HTTP/2.0"]

..and then the request is blocked

ModSecurity: Access denied with code 403 (phase 2). Matched "Operator `Ge' with parameter `5' against variable `TX:ANOMALY_SCORE' (Value: `13' ) 
[file "/etc/nginx/modsec/coreruleset-3.3.0/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] 
[line "80"] 
[id "949110"] 
[msg "Inbound Anomaly Score Exceeded (Total Score: 13)"] 
[data ""] 
[severity "2"] 

So I'm totally surprised and I don't know what can I do about this since the rules seem legit but also I don't feel like breaking any of them.

EDIT (responding to @franbuehler comment):

Testing with curl:

curl -v -d '{"arg":"foo", "arg2":bar}' -H "content-length: 25" -H "content-type: application/json" -H "x-format-output: txt-matched-rules" "https://example.com/livewire/update"

I'm also being 403 blocked:

---EdzD52pk---A--
[22/Jan/2024:12:50:45 +0000] 1705927845 127.0.0.1 57452 127.0.0.1 443
---EdzD52pk---B--
POST /livewire/update HTTP/2.0
host: example.com
user-agent: curl/7.81.0
accept: */*
x-format-output: txt-matched-rules
content-length: 25
content-type: application/json


---EdzD52pk---F--
HTTP/2.0 403
Server: nginx/1.24.0
Date: Mon, 22 Jan 2024 12:50:45 GMT
Content-Length: 153
Content-Type: text/html
Connection: close

---EdzD52pk---H--
ModSecurity: Warning. Matched "Operator `Rx' with parameter `^\d+$' against variable `REQUEST_HEADERS:content-length' (Value: `25' ) [file "/etc/nginx/modsec/coreruleset-3.3.0/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf"] [line "127"] [id "920160"] [rev ""] [msg "Content-Length HTTP header is not numeric"] [data "25"] [severity "2"] [ver "OWASP_CRS/3.3.0"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-protocol"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/210/272"] [hostname "127.0.0.1"] [uri "/livewire/update"] [unique_id "1705927845"] [ref "v114,2"]
ModSecurity: Warning. Matched "Operator `Rx' with parameter `^[\w/.+-]+(?:\s?;\s?(?:action|boundary|charset|type|start(?:-info)?)\s?=\s?['\"\w.()+,/:=?<>@-]+)*$' against variable `REQUEST_HEADERS:content-type' (Value: `application/json' ) [file "/etc/nginx/modsec/coreruleset-3.3.0/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf"] [line "915"] [id "920470"] [rev ""] [msg "Illegal Content-Type header"] [data "application/json"] [severity "2"] [ver "OWASP_CRS/3.3.0"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-protocol"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/255/153"] [tag "PCI/12.1"] [hostname "127.0.0.1"] [uri "/livewire/update"] [unique_id "1705927845"] [ref "v131,16t:lowercase"]
ModSecurity: Warning. Matched "Operator `Rx' with parameter `^(?i:(?:[a-z]{3,10}\s+(?:\w{3,7}?://[\w\-\./]*(?::\d+)?)?/[^?#]*(?:\?[^#\s]*)?(?:#[\S]*)?|connect (?:\d{1,3}\.){3}\d{1,3}\.?(?::\d+)?|options \*)\s+[\w\./]+|get /[^?#]*(?:\?[^#\s]*)?(?:#[\S]*)?)$' against variable `REQUEST_LINE' (Value: `POST /livewire/update HTTP/2.0' ) [file "/etc/nginx/modsec/coreruleset-3.3.0/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf"] [line "47"] [id "920100"] [rev ""] [msg "Invalid HTTP Request Line"] [data "POST /livewire/update HTTP/2.0"] [severity "4"] [ver "OWASP_CRS/3.3.0"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-protocol"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/210/272"] [hostname "127.0.0.1"] [uri "/livewire/update"] [unique_id "1705927845"] [ref "v0,30"]
ModSecurity: Access denied with code 403 (phase 2). Matched "Operator `Ge' with parameter `5' against variable `TX:ANOMALY_SCORE' (Value: `13' ) [file "/etc/nginx/modsec/coreruleset-3.3.0/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] [line "80"] [id "949110"] [rev ""] [msg "Inbound Anomaly Score Exceeded (Total Score: 13)"] [data ""] [severity "2"] [ver "OWASP_CRS/3.3.0"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-generic"] [hostname "127.0.0.1"] [uri "/livewire/update"] [unique_id "1705927845"] [ref ""]