Improve DoS protection rules against race condition (981048/912040)
See original GitHub issue_Issue originally created by user loudly-soft on date 2016-05-27 12:34:00. Link to original issue: https://github.com/SpiderLabs/owasp-modsecurity-crs/issues/346._
It has been reported in the owasp-modsecurity-core-rule-set mailing list that the DOS protection rules can trigger false positives. The audit log would report:
Warning. Operator GE matched 2 at IP:dos_burst_counter. [file “/etc/httpd/modsecurity.d/activated_rules/modsecurity_crs_11_dos_protection.conf”] [line “44”] [id “981049”] [msg “Potential Denial of Service DoS) Attack from X.X.X.X - # of Request Bursts: 5”]
However, counting the actual number of requests made by the IP during the purported burst time slice in Apache access_log, the number would show that it’s less than the specified burst counter threshold (tx.dos_counter_threshold
) so it’s a false alarm.
While the report was submitted 3 years ago in 2013, I’m encountering the same problem since I started working with ModSecurity recently. I have tracked the issue down to rule 981048 as a result of concurrent requests. In short, ip.dos_burst_counter
would jump from 0 to ≥ 2 while handling concurrent requests, therefore, causing a block erroneously. The gory details can be found on my blog. In the meantime, I have patched the problem by replacing rule 981048 with 2 chained rules to ensure that ip.dos_burst_counter
doesn’t jumped from 0 to ≥ 2 and trigger a false alarm.
#
# Check DOS Counter (Tick)
# If the request count is greater than or equal to user settings,
# we then set the burst counter to 1 if it's 0
#
SecRule IP:DOS_COUNTER "@ge %{tx.dos_counter_threshold}" "chain,phase:5,id:'981048',t:none,nolog,pass"
SecRule &IP:DOS_BURST_COUNTER "@eq 0" "setvar:ip.dos_burst_counter=1,expirevar:ip.dos_burst_counter=%{tx.dos_burst_time_slice},setvar:!ip.dos_counter"
#
# Check DOS Counter (Tock)
# If the request count is greater than or equal to user settings,
# we then set the burst counter to 2 if it's 1
#
SecRule IP:DOS_COUNTER "@ge %{tx.dos_counter_threshold}" "chain,phase:5,id:'981050',t:none,nolog,pass"
SecRule &IP:DOS_BURST_COUNTER "@ge 1" "setvar:ip.dos_burst_counter=2,expirevar:ip.dos_burst_counter=%{tx.dos_burst_time_slice},setvar:!ip.dos_counter"
So far, the patch has been working on my server (in detection mode) with ModSecurity 2.8. I’m wondering if anybody else has bumped into this problem and came up with a fix. If not, does anyone see anything wrong with my patch? Thanks in advance.
Issue Analytics
- State:
- Created 3 years ago
- Comments:7
Top GitHub Comments
User csanders-git commented on date 2016-11-19 23:39:17:
Hmm this is actually something we should carefully consider – good blog post. As zimmerle is fond of noting, local collections have all sorts of underlying problems with timing when using threaded web servers. The suggestion made in the blog may (probably will) still be applicable for the updated rules.
User lifeforms commented on date 2017-05-01 19:20:02:
Closing this in favor of the PR #735, please continue any discussion there! Thanks for the report!