owasp-modsecurity / ModSecurity

ModSecurity is an open source, cross platform web application firewall (WAF) engine for Apache, IIS and Nginx. It has a robust event-based programming language which provides protection from a range of attacks against web applications and allows for HTTP traffic monitoring, logging and real-time analysis.
https://www.modsecurity.org
Apache License 2.0
7.67k stars 1.54k forks source link

SanitiseArg does not work in RequestBody #3089

Open Seppl2202 opened 2 months ago

Seppl2202 commented 2 months ago

SanitiseArg does not work in RequestBody This time without messed up markdown :)

Taken right from the docs: https://github.com/owasp-modsecurity/ModSecurity/wiki/Reference-Manual-(v2.x)#user-content-sanitiseArg

I want to sanitiese two password fields in a POST body, but the Rule is not working. I am on Ubuntu 22.04.03 LTS for testing and Apache 2.4.52

I have defined five rules (for each phase for testing, although only phase 2 should be relevant) in my custom rules:. see the waf_adaption attachment: SecAction "auditlog,phase:2,id:131,sanitiseArg:password1,sanitiseArg:password2" Logs and dumps

Output of:

  1. DebugLogs (level 9)
  2. AuditLogs
  3. Error logs: is empty
  4. If there is a crash, the core dump file: n crash

See the attached files, also the modsecurity configuration

To Reproduce

Steps to reproduce the behavior:

curl 'http://localhost/test' -X POST -H 'User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:120.0) Gecko/20100101 Firefox/120.0' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' -H 'Accept-Language: en-US,en;q=0.5' -H 'Accept-Encoding: gzip, deflate, br' -H 'Connection: keep-alive' -H 'Upgrade-Insecure-Requests: 1' -H 'Sec-Fetch-Dest: document' -H 'Sec-Fetch-Mode: navigate' -H 'Sec-Fetch-Site: same-origin' -H 'Sec-Fetch-User: ?1' -H 'Origin: http://localhost' -H 'Pragma: no-cache' -H 'Cache-Control: no-cache' --data-raw $'password1=xyz&password2=test&inj=1\' or 1=1;--'

Expected behavior

I would expect that password1 and password2 are sanitised in the audit log, when appearing in the request body.

Server (please complete the following information):

Rule Set (please complete the following information):

I added the configuration and log files as an attachmen

Add any other context about the problem here. modsec_debug.log modsec_audit.log modsecurity.txt security2.txt waf_adaption.txt

airween commented 2 months ago

Hi @Seppl2202,

thanks for reporting.

First of all I tried your SecAction lines with id 131-135, and I got this in my audit.log:

--b165c225-C--
password1=***&password2=***&inj=1'  or 1=1;--
--b165c225-F--

But I see in my log many other rules too, eg:

Message: Warning. Found 5 byte(s) in ARGS:inj outside range: 38,44-46,48-58,61,65-90,95,97-122. [file "/home/airween/src/coreruleset/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf"] [line "1767"] [id "920273"] [msg "Invalid character in request (outside of very strict set)"] [data "ARGS:inj=1'  or 1=1;--"] [severity "CRITICAL"] [ver "OWASP_CRS/4.0.0-rc2"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-protocol"] [tag "OWASP_CRS"] [tag "capec/1000/210/272"] [tag "paranoia-level/4"]

Message: Warning. Match of "rx [0-9]\\s*\\'\\s*[0-9]" against "MATCHED_VAR" required. [file "/home/airween/src/coreruleset/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf"] [line "1155"] [id "932240"] [msg "Remote Command Execution: Unix Command Injection evasion attempt detected"] [data "Matched Data: 1'  or found within ARGS:inj: 1'  or 1=1;--"] [severity "CRITICAL"] [ver "OWASP_CRS/4.0.0-rc2"] [tag "application-multi"] [tag "language-shell"] [tag "platform-unix"] [tag "attack-rce"] [tag "paranoia-level/2"] [tag "OWASP_CRS"] [tag "capec/1000/152/248/88"] [tag "PCI/6.5.2"]

Note that I'm using CRS 4.0.0 (rc2), but I think the point is that I use that on PL4, therefore there are 2 rules which checks the ARGS target - may be that's necessary to apply the sanitiseArg action(?).

Could you check your instance with a higher PL?

Also: @dune73 could you take a look at this?

dune73 commented 2 months ago

This sanitization stuff is so brittle.

I do not know why it does not work for @Seppl2202, but I would not rule out the status 404 being the reason. Try to reproduce with a 200.

airween commented 2 months ago

but I would not rule out the status 404 being the reason. Try to reproduce with a 200.

Just FYI: I also got 404.

airween commented 2 months ago

I tried both with response 404 and 200 - the arguments are sanitized.

--89968044-C--
password1=***&password2=***&inj=1'  or 1=1;--
--89968044-F--
HTTP/1.1 404 Not Found
Content-Length: 271
Content-Type: text/html; charset=iso-8859-1

and

--89968044-C--
password1=***&password2=***&inj=1'  or 1=1;--
--89968044-F--
HTTP/1.1 200 OK
Upgrade: h2,h2c
Connection: Upgrade
Last-Modified: Fri, 03 Sep 2021 16:09:19 GMT
ETag: "29cd-5cb1985966531"
Accept-Ranges: bytes
Content-Length: 10701
Content-Type: text/html

So @Seppl2202 could you check with higher PL?

Seppl2202 commented 2 months ago

Thanks for your tests, I will try to use CRS4 today or tomorrow