Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save rpfilomeno/6b0431ed1a416104bafc to your computer and use it in GitHub Desktop.

Select an option

Save rpfilomeno/6b0431ed1a416104bafc to your computer and use it in GitHub Desktop.
ModSecurity Tricks
A good way to defend against brute force attacks is to allow a certain number of login attempts, say three, and after that start delaying or blocking further attempts. Let's see how we can use ModSecurity to accomplish this.
If your login verification page is situated at yoursite.com/login, then the following rules will keep track of the number of login attempts by users:
#
# Block further login attempts after 3 failed attempts
#
<LocationMatch ^/login>
# Initalize IP collection with user's IP address
SecAction "initcol:ip=%{REMOTE_ADDR},pass,nolog"
# Detect failed login attempts
SecRule RESPONSE_BODY "Username does not exist" "phase:4,pass,setvar:
ip.failed_logins=+1,expirevar:ip.failed_logins=60"
# Block subsequent login attempts
SecRule IP:FAILED_LOGINS "@gt 3" deny
</Location>
The rules initialize the ip collection and increase the field ip.failed_logins after each failed login attempt. Once more than three failed logins are detected, further attempts are blocked. The expirevar action is used to reset the number of failed login attempts to zero after 60 seconds, so the block will be in effect for a maximum of 60 seconds.
Another approach is to start delaying requests once the threshold number of login attempts has been reached. This has the advantage of not denying access in case a legitimate user has actually forgotten his password and needs more attempts to remember it. Here are the rules to do that:
#
# Throttle login attempts after 3 failed attempts
#
<LocationMatch ^/login>
SecAction "initcol:ip=%{REMOTE_ADDR},pass,nolog"
SecRule RESPONSE_BODY "Username does not exist" "phase:4,pass,setvar:
ip.failed_logins=+1,expirevar:ip.failed_logins=10"
SecRule IP:FAILED_LOGINS "@gt 3" "phase:4,allow,pause:3000"
</Location>
The pause action is what delays the request, and the time specified is in milliseconds, so the above will delay the response for three seconds once the limit of three failed login attempts has been exceeded.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment