This has come up many times in the forum so I decided to demonstrate a method using a database table and the ip address of the client.

The goal is to keep track of the number of times a login attempt is made from the same ip address within a defined number of seconds. In order to do that the first thing the function does is remove all previously stored attempts from the table that are too old to have happened within that number of seconds. This will keep the table from growing to the point where it might slow the server down and keep it from using too much space. The next step is to add this new attempt to the table, and finally, the script counts the number of attempts from this current ip address and returns the value. From there it's a simple matter for the script to decide whether or not to allow another login attempt based on the defined number of maximum attempts.

Replies To: Limiting login attempts

However, I'm not saying you're developing a website that's going to have a lot of traffic but, would querying the database be a resource hog for checking something simple. I haven't done this before but would it better to do this using Session data or is that more of an overhead?

The idea behind removing old information from the table is to keep it from consuming resources. Even if a session would use fewer resources than the database its important to remember that a bot doesn't need to store the session cookie — or it could store it, but delete it every time the bot fails to login. That's not to say this method is the ideal way either. To get around it a bot could be written to continually change proxy servers, so if you wanted to be extra secure you might use a hybrid of this and session variables.

The idea behind removing old information from the table is to keep it from consuming resources. Even if a session would use fewer resources than the database its important to remember that a bot doesn't need to store the session cookie — or it could store it, but delete it every time the bot fails to login. That's not to say this method is the ideal way either. To get around it a bot could be written to continually change proxy servers, so if you wanted to be extra secure you might use a hybrid of this and session variables.

If someone is going to make it change proxy servers, they're not going to bother storing session variables. IP based detection also is horrible to people behind a NAT (Starbucks). I would generally recommend you just have a login form, but make it wait two seconds before you actually check the password. This reduces the number of guesses they can make drastically, and is impossible to circumvent.

If you REALLY want to go down the IP based route, you might want to check the user agent as well.

P.S. Any query to a database can be quite expensive, another reason I don't like methods that store things.

They don't have a choice when it comes to storing session variables, only the session id cookie. Even that must be stored to successfully login, so
they only have the option to delete it after an attempt fails.

As for IP addresses being a problem behind NAT, it's not likely that you'll have two or more legitimate users trying to log in at the same time from the same network. Even if they are, all they need to do is have one wait a few seconds!

I suppose the computational expense is relative. If you don't have bots trying to hack in, then why bother with this at all, but if you do, then the bulk of your processing time without something like this is going to be spent giving the hacker opportunities to break in.