On Tue, Oct 30, 2012 at 8:20 PM, Liddy <lidelyncaballes@gmail.com> wrote:

# Setup brute force detection against wp-login.
# React if block flag has been set.
SecRule user:bf_block "@gt 0" "deny,status:401,log,msg:'ip address blocked for 5 minutes, more than 15 login attempts in 3 minutes.'"

Hi Liddy,

Out of curiosity, why are you using the USER collection to hold the block flag but using the IP collection to track the login attempts? I think it makes more sense to set the flag in the IP collection (or possibly SESSION if the session token remains the same for the various login attempts). I would also specify the phase your blocking in in the above rule. Finally, I assume your initializing the collections elsewhere in your rules. 
# Setup Tracking.
# On a successful login, a 302 redirect is performed, a 200 indicates login failed.

SecRule REQUEST_URI "wp-login.php" "phase:1, chain"
SecRule RESPONSE_STATUS "^302" "phase:5,t:none,nolog,pass,setvar:ip.bf_counter=0"

You can't have a chained rule run in two different phases. Move everything into phase 3 as that's where you first have access to the response status and set it once in the first part of the chain. In addition, disruptive actions need to be in the first rule as well, thus something like this could work:

SecRule REQUEST_URI "wp-login.php" "phase:3,id:2,pass,nolog,t:none,chain"
  SecRule RESPONSE_STATUS "^302" "setvar:ip.bf_counter=0"

SecRule REQUEST_URI "wp-login.php" "phase:1, chain"
SecRule RESPONSE_STATUS "^200" "phase:5,chain,t:none,nolog,pass,setvar:ip.bf_counter=+1,deprecatevar:ip.bf_counter=1/180"
SecRule ip:bf_counter "@gt 3" "t:none,setvar:user.bf_block=1,expirevar:user.bf_block=300,setvar:ip.bf_counter=0"

Besides for adjusting the phases and moving the meta data around, I would separate the last part of the chain to be its own rule. Also, unlike expirevar, deprecatevar needs to run on every request, so use a SecAction instead, i.e.:

SecRule REQUEST_URI "wp-login.php" "phase:3,id:4,chain,t:none,nolog,pass"
  SecRule RESPONSE_STATUS "^200" "setvar:ip.bf_counter=+1

SecAction ifd:5,phase:5,nolog,pass,deprecatevar:IP.bf_counter=1/180"

SecRule IP:bf_counter "@gt 3" "phase:3,id:6,setvar:ip.bf_block=1,expirevar:ip.bf_block=300,setvar:ip.bf_counter=0"

FWIW, I didn't test any of these rules, so YMMV.

 - Josh

Thoughts? Improvements?


Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
mod-security-users mailing list
Commercial ModSecurity Rules and Support from Trustwave's SpiderLabs: