There are several useful answers on SO regarding prevention of brute forcing a password of a web service by applying throttling. I couldn't find any good numbers though and I have little expertise in this area, so the question is:
How many attempts does it usually take to brute-force an average password of 6 or more characters (with no additional knowledge that may help, but taking into account that passwords are probably prone to dictionary attacks) and based on that, what are meaningful limits to apply to the throttling algorithm without disrupting the user experience?
This is my current scheme:
- The login form uses a nonce, so the attacker has to wait for a complete request cycle to complete to both get the result of the login attempt and retrieve a new token.
I allow the login form to be retrieved 50 times per IP with less than a minute between requests, after that the IP will be blocked for 1 minute. Any new attempts within this one minute will restart the timeout.There's asleep
applied for each fetching of the login page of# of attempts / 5
, so after 5 requests with less than a minute between requests it'll take > 1 second to fetch the form, after 10 requests > 2 seconds, etc.Additionally, I'm only allowing 100 failed login attempts per user account with 2 hours between attempts, after that the account is blocked for 2 hours.- To avoid frequent DoS'ing of accounts, IPs can be whitelisted (no limits applied) or blacklisted (any login attempt ignored completely).
Based on the answers so far, I have tweaked it to work like this:
- Retrieving the login form is progressively slowed down on a per IP basis. Each new request is slept for
# of requests / 2
seconds. The counter is reset after 10 minutes of no login activity. - I'm keeping a FIFO stack of login attempts for each IP. If an IP fails to log in 30 times within 2 hours, it's suspended. I'm also keeping a list of number of suspensions per IP, and the suspension time is calculated as
2 ^ (# of suspensions + 1) hours
. This should lead to a rapid de facto blacklisting of continually offending IPs. - Additionally, if an account failed to log in 20 times within one day it's being suspended for 2 hours. I'm not too sure about this measure yet, since this means accounts can be DoS'd quite easily. Short of a massive distributed botnet though, offending IPs should become de facto blacklisted faster than an account can be permanently DoS'd. It's also quite an effective measure to protect an account.
I think these limits should not harm normal users, even ones that regularly forget their password and try to log in several times. The IP limits should also work okay with heavily NAT'ed users, given the average size of the service. Can somebody prove this to be efficient or inefficient with some solid math? :)