ModSecurity icon indicating copy to clipboard operation
ModSecurity copied to clipboard

408 http code generated by mod_reqtimeout is not detected

Open ShaiMagal opened this issue 2 years ago • 15 comments

Describe the bug

408 http code is not detected

Logs and dumps

  1. SecDebugLog level 9: empty

If you change rule from "@streq 408" to "@streq 200" (for TEST PURPOSES ONLY), it blocks correctly and fill the SecDebugLog(SecDebugLog = 9) with informations. If you leave "@streq 408", debug log is empty and not blocking.

  1. Apache error log: empty

  2. Output of apache access log:

XXX.XXX.XXX.XXX - - [30/Oct/2023:16:45:33 +0100] "GET / HTTP/1.1" 408 448
XXX.XXX.XXX.XXX - - [30/Oct/2023:16:45:33 +0100] "GET / HTTP/1.1" 408 448
XXX.XXX.XXX.XXX - - [30/Oct/2023:16:45:33 +0100] "GET / HTTP/1.1" 408 448
XXX.XXX.XXX.XXX - - [30/Oct/2023:16:45:33 +0100] "GET / HTTP/1.1" 408 448
XXX.XXX.XXX.XXX - - [30/Oct/2023:16:45:33 +0100] "GET / HTTP/1.1" 408 448
XXX.XXX.XXX.XXX - - [30/Oct/2023:16:45:33 +0100] "GET / HTTP/1.1" 408 448
XXX.XXX.XXX.XXX - - [30/Oct/2023:16:45:33 +0100] "GET / HTTP/1.1" 408 448
XXX.XXX.XXX.XXX - - [30/Oct/2023:16:45:33 +0100] "GET / HTTP/1.1" 408 448
XXX.XXX.XXX.XXX - - [30/Oct/2023:16:45:33 +0100] "GET / HTTP/1.1" 408 448
XXX.XXX.XXX.XXX - - [30/Oct/2023:16:45:33 +0100] "GET / HTTP/1.1" 408 448

To Reproduce

  1. Install Ubuntu + apache + reqtimeout + mod security
  2. Use rules below
  3. Make slowloris attack from server to server: wget https://raw.githubusercontent.com/GHubgenius/slowloris.pl/master/slowloris.pl && perl slowloris.pl -dns SERVER_IP -port 80 -timeout 3 -num 750
  4. You will see, apache 408 in access.log, but modsecurity do nothing.

If you change rule detection "408" to "200", it is working (blocking). So, there is any problem with http code 408. Not with the rule itself.

Expected behavior

Detect 408 http code correctly and block attacker

Server (please complete the following information): Ubuntu 20 TLS (Ubuntu 16 and 18 same problem) Apache/2.4.58 (Ubuntu) + mod_reqtimeout (lower Apache 2.4.x versions same problem) libapache2-mod-security2 2.9.3-1ubuntu0.1 (2.9.2 and 2.9.0 same problem)

Rule Set (please complete the following information):

SecRule RESPONSE_STATUS "@streq 408" "id:20,phase:5,t:none,nolog,pass,setvar:ip.slow_dos_counter=+1,expirevar:ip.slow_dos_counter=60,ctl:ruleEngine=On"
SecRule IP:SLOW_DOS_COUNTER "@gt 5" "id:21,phase:1,t:none,log,deny,status:403,msg:'SlowlorisAttack',ctl:ruleEngine=On"

Additional context

ShaiMagal avatar Oct 30 '23 15:10 ShaiMagal

Hello @ShaiMagal ,

To clarify: the 408 is being generated by that other mod, right (i.e. mod_reqtimeout)?

In that case, when you write the expectation 'Detect 408 http code correctly and block attacker', it's that other mod that is blocking that transaction, isn't it?

In which case, the actual problem is just ModSecurity's non-receipt of the actual response code (408), right?

martinhsv avatar Oct 30 '23 18:10 martinhsv

Hello @ShaiMagal ,

To clarify: the 408 is being generated by that other mod, right (i.e. mod_reqtimeout)?

In that case, when you write the expectation 'Detect 408 http code correctly and block attacker', it's that other mod that is blocking that transaction, isn't it?

In which case, the actual problem is just ModSecurity's non-receipt of the actual response code (408), right? Hi @martinhsv

  • I don't know what is it generating, but I think, it's apache itself, but maybe its via this module, don't know (I don't know source code of Apache/mod_requtimeout). mod_reqtimeout is classic mod for mitigation slowloris and in past mod_security can handle this 408 for block attacker. Without this mod_security can't be used for mitigation slowloris (of course, there are other ways).

  • mod_security should block attacker. If I change rule "@streq 408" -> "@streq 200", it block "attacker" without problems. So, blocking is working well, but not with 408 http code.

  • So, it's looks like, everything is working well with http code 200 (for testing purposes rule working well), but after 408 not working (not detecting). Maybe any incompatibility with this module, don't know, but mod_reqtimeout is native apache module and this sucessfully log do apache log 408... I don't know, why mod_security can't handle this :/

ShaiMagal avatar Oct 30 '23 19:10 ShaiMagal

@ShaiMagal ,

To be clear, each transaction that triggers a 408 (presumably produced by the action of mod_reqtimeout, since that is what it is intended to do) is being 'blocked' by that non-ModSecurity functionality. I.e. when the client receives the 408 for a particular transaction, that means that HTTP request has been rejected.

There is the separate blocking that you have coded in your rule 21 -- and that blocking is intended to be performed by ModSecurity. And that rule 21, could (in principle) deny requests from the flagged ip address even if it is not blocked by mod_reqtimeout. Of course for rule 21 to work requires ModSecurity to have detected the 408s from earlier transactions.

The only real question I see here is why ModSecurity is not successfully informed by Apache about the 408 response codes. A potential resolution of this might require an adjustment to how ModSecurity is plugged into Apache ... or it might require a change to mod_reqtimeout or to Apache itself.

martinhsv avatar Oct 31 '23 14:10 martinhsv

The only real question I see here is why ModSecurity is not successfully informed by Apache about the 408 response codes. A potential resolution of this might require an adjustment to how ModSecurity is plugged into Apache ... or it might require a change to mod_reqtimeout or to Apache itself. Yes, it is the main problem. 408 response code working, other codes working... So not problem at rule, only with connection 408 + modsec + apache + reqtimeout..

So, what next? :)

ShaiMagal avatar Oct 31 '23 14:10 ShaiMagal

When a standard slowloris attack (very slow, incremental sending of request headers) is halted by mod_reqtimeout, I don't see a good way to have ModSecurity automatically report on this.

The problem is that ModSecurity never sees the request at all. Note, for example, that the ModSecurity debug log (at level 9) is empty in these cases.

I might have thought that using an Apache ErrorDocument directive might be a way to detect the inital 408 and redirect to a custom408errorpage.html that ModSecurity could detect. But an initial trial of that workaround was not successful. You could consider experimenting with something along those lines, if you were so inclined.

There are a couple of other options that you could consider but neither are great:

  1. With mod_reqtimeout running on the main server, move ModSecurity to a reverse proxy in front of the web server
  2. Use the reqtimeout messages that go to apache's error.log. You could even extract these and include the information in the ModSecurity audit log if you really need to (perhaps via lua script or other mechanism). This would be somewhat clunky and may suffer from timing issues.

martinhsv avatar Nov 14 '23 17:11 martinhsv

I don't see a good way to have ModSecurity automatically report on this.

Point is, modsecurity should block this IP adress what are attacking. mod_reqtimeout must report this to modsecurity for blocking IP. mod_reqtimeout is only partially protection. Blocking of IP is next level, and modsecurity should do this.

In past there is a lot of references modsecurity works with mod_reqtimeout. So, what changed in time?

We aren't talking about modsecurity should investigace it, we are talking about, modsecurity must block IP adress via 408 provided http_code via mod_reqtimeout.

2. Use the reqtimeout messages that go to apache's error.log. You could even extract these and include the information in the ModSecurity audit log if you really need to (perhaps via lua script or other mechanism). This would be somewhat clunky and may suffer from timing issues.

Yes, we do this. reqtimeout log to apache error.log. But modsecurity don't get this information. Why I should programming any specific way for connection? Modsecurity should be native working with req_timeout.

Check this, in past it was working: https://github.com/SpiderLabs/owasp-modsecurity-crs/issues/667

So, why not now?

Easier option for me is program special script for monitoring log for 408, but it's overkill, we use modsecurity for all of this job, so, why to split to another solo script? It's not effective.

We will be happy to modsecurity will works with mod_reqtimeout like in past..

ShaiMagal avatar Nov 14 '23 17:11 ShaiMagal

It's not clear to me that that Nov. 2016 issue indicates that the interoperability worked as you expect at that time. That is not explicitly stated.

In any case, I tried ModSecurity v2.9.1 (which was the most recent version of ModSecurity in Nov. 2016) and saw no difference. If you believe some change in the ModSecurity engine has resulted in a change of behaviour, you're certainly free to build older versions and experiment yourself.

martinhsv avatar Nov 14 '23 18:11 martinhsv

@martinhsv I don't know where is the problem, I already waste a few days of testing. I tried more versions of modsec and apache, not working. I don't know why..

So, where is the problem? I don't know if this is problem modsecurity, but... Where should by issue open? Where can be problem?

Tested on X system with Ubuntu versions 16-22, more apache versions, more modsec version, but not working.

Don't know why...

Who can help me and other people with this problem? :)

Or I must write my own script for detecting it via log directly? It's overkill....... Better to use native modsecurity function.

ShaiMagal avatar Nov 15 '23 10:11 ShaiMagal

Any recommendation? I think protection is priority for modsecurity and make it working with 408 http code will be awesome.

ShaiMagal avatar Dec 20 '23 11:12 ShaiMagal

@ShaiMagal ,

I did provide two possible suggestions here: https://github.com/SpiderLabs/ModSecurity/issues/3007#issuecomment-1810722958 .

Beyond that, any further time to be spent on this item will be prioritized against other open issues.

martinhsv avatar Dec 20 '23 14:12 martinhsv

@martinhsv I read this. So,it isn't important for modsecurity to make partial protection against slowloris attack? I didn't say "now", but in few months? or one year? But OK, I will try to handle it

Because you wrote "When a standard slowloris attack (very slow, incremental sending of request headers) is halted by mod_reqtimeout, I don't see a good way to have ModSecurity automatically report on this.", yes, but this only make 408 and we need to block this IP, because we don't want to allow them to continue their requests.

But I might have thought that using an Apache ErrorDocument directive might be a way to detect the inital 408 and redirect to a custom408errorpage.html that ModSecurity could detect. - can you explain me it little more with any "fast example"? If there is any "simple" solution, I will happy for it.

Because you wrote 2 options and first one (reverse proxy) is not possible because incompatibility with other features and second one is unfamiliar for me (lua script) :/

Thank you.

ShaiMagal avatar Dec 24 '23 21:12 ShaiMagal

Btw, here is pointed to same feature for modescurity like I wrote and should be working:

https://www.trustwave.com/en-us/resources/blogs/spiderlabs-blog/updated-modsecurity-advanced-topic-of-the-week-mitigating-slow-http-dos-attacks/

ShaiMagal avatar Feb 19 '24 15:02 ShaiMagal