The Blog


Got something to say? Feel free, we want to hear from you! Leave a Comment

  1. iJeff says:

    The person who wrote this article sounds brilliant. I would have his babies if that option was available.

  2. Grateful says:

    Thanks for posting this, it addressed all the questions I had…and a few I didn’t. Porting to Ruby commencing now…

  3. Thanks for your excellent thoughts. I used them as underlying principles for a new WordPress plugin,

    You suggest deleting the failed login data once the user logs in successfully. But what if the attacker got lucky and gets in? I decided to have a cutoff on the number of failed logins after which if they do log in, I immediately force them out and require they use the lost password process. This verifies their identity via email on record and prevents damage from being done.

  4. Jesse says:

    Thank you for this! Very informative. I have a question about detecting failed attempts though…

    I notice you are adding response times based on number of failed attempts. This is genious! However, I am wondering if I should be storing number of recently failed attempts into a database with timestamps? I assume a bruteforcer can change their IP address and refresh the login form between attempts. We also know that we cannot trust sessions. That said, if the form is refreshed between attempts, and the IP appears different each time, the login form has no way of knowing how many failed attempts are being made because it will only ever record one failed attempt before refreshing page and IP. This is why I ask if I should be recording failed attempts into a database with timestamps so that the login form can check the database for frequency of failed attempts before deciding response time, etc. What are your thoughts on this?

    • Bryan Rite says: (Author)

      Hey Jesse,

      You are correct, we can’t rely on the form or the session at all. I use a simple counter in the database based on the login (email, username, etc.). When a password attempt fails for that particular login, we increment the counter.

      To prevent account locking over time, I’ve used a couple of schemes to success: you can periodically decrement the counter with a background process or for every successful login, decrement the counter by a few points (or even set it to zero).

  5. Jesse says:

    Do I need to store the counter in the database? Here is my plan… I’d like to have a table which stores login attempts (storing attempted usernames, mysql timestamps for each attempt, and whether or not each attempt was a success or failure). Instead of actually storing a counter int he database, what about grabbing all rows containing entered username that are newer than X minutes, and adding a delay if X attempts are made within that 5 minutes. If I am storing login attempts in database with timestamps, do I need to actually store a delay counter value in the database, or can I just run a script which queries these timestamps and generates delay value in realtime? Or are both safe options?

    • Bryan Rite says: (Author)

      Yup, that sounds like a good alternate implementation. It does the same thing in a more auditable way.

      I’ve recently been using Redis (or any key-value store) to store these things. It is much faster and less prone to DDOS, for login data that doesn’t necessarily rely on the advantages of a RDMS. Redis, for example, can easily aggregate the results for you as well.

  6. Julian says:

    why are you using the BruteForceProtection() regardless if the user is valid. If the login is correct, why should the user wait?
    Therefore, thank you very much for this post!

  7. Julian says:

    One question: How to integrate the vertical brute force into this horizontal? In my opinion you have to choose between one, right?

Trackbacks for this post

  1. Principles to Apply When Preventing Brute Force Attacks | Ian Dunn

Leave a Comment

Let us know your thoughts on this post.