8

My login form uses Ajax so it doesn't need to reload if the password is wrong. A PHP script process the request and creates the session if the credentials are right. My idea is to have the PHP script sleep to mitigate a brute force attack. At first it wouldn't sleep at all but after that I'm not sure.

How long does a form require an attacker to wait until they can try the next password? Also are complete lock outs still recommended? If yes after how many tries?

1
  • 1
    You may be interested in the lockout policy described in my answer here: stackoverflow.com/questions/16133884/… . The bruteforcing quickly converges to a "simple" denial-of-service attack, and there are defenses against that. Sleep() will actually help the attacker.
    – LSerni
    Apr 29, 2013 at 22:26

3 Answers 3

11

Since HTTP is a stateless protocol, there is no concept of a wait time between tries. The attacker can simply spawn multiple processes, and try many passwords simultaneously.

A common way to deal with the problem, and to lessen the impact on your server is by implementing a lockout policy, where you maintain a counter to track the incorrect password attempts for a given username over some specific period of time (5 wrong attempts in 5 minutes is a common default) and simply quit attempting to authenticate requests with that username for the next few minutes.

3
  • 2
    I kind of don't get your reasoning. Why not have login for a particular username take longer and longer regardless of the requester's IP address?
    – Celeritas
    Apr 29, 2013 at 20:59
  • 4
    Because eventually the attacker can fire so many concurrent requests that all the threads in your web server's threadpool will be used up, just waiting to respond to his requests, and not able to serve other, legitimate requests. Having to wait 5 or 10 seconds for a response is only going to encourage him to increase the number of concurrent requests being made...Meaning there's no actual slow down effect, as long as the server stays up.
    – Xander
    Apr 29, 2013 at 21:04
  • 1
    @Celeritas In other words, you make me wait 10 times as long for a response, I just send you ten times as many concurrent requests, and I get to try the same number of passwords in the same amount of time, and your server suffers for it.
    – Xander
    Apr 29, 2013 at 21:05
7

A hacker can easily spawn multiple AJAX calls in parallel, this will bypass your sleep thing. And you may end up clogging server resources. Instead, do the following:

  • Start showing CAPTCHAs after three incorrect attempts from an IP
  • After an incorrect attempt, block all new login requests to your server from that IP for a period of time. Increment this on every failed attempt.
  • Keep a log and note spikes of activity. If someone is trying to bruteforce, you ought to make note of that and counter it.
2
  • Your #2 sounds very similar to what my initial idea was. Is the difference that each script that is sleeping uses server resources but blocking an IP address doesn't really use resources?
    – Celeritas
    Apr 29, 2013 at 21:57
  • @Celeritas: Simply sleeping will not prevent the user from spawning another 100 requests, which will all spawn more sleeping threads on your server. If you block the IP, then these new requests will just die immediately and the threads will be intermittent. Apr 29, 2013 at 22:02
1

USER ACCOUNTS

A lockout policy (or use of php sleep function) to protect a login form could in some cases be even worse (or much worse) than a brute force attack, in particular if the attacker has access to user account login data: for example, in cases where public usernames are used for authentication, which is bad in general, if avoidable. The attacker could lock registered users again and again (DOS), leading to a real disaster. Never do that on a public web site. It is probably much easier for an attacker to exploit an account locking system based on login attempts, than it is for a developer to create an effective one. A better solution is to keep good practices: hide as much information as possible, as usual, while forcing users to create good passwords. This way, brute force attacks could be totally useless: the attacker will need too many resources to achieve something. In this scenario, for example, use emails only to log in (or any other user data that is not public), never public usernames, and never make them visible and collectable to other users or public. But do not apply a lockout policy on user accounts.

IPs

A good DOS attack is made from many different ips. That said, you could apply a lockout policy on the web server to avoid DOS and Brute Force attacks by detecting excessive requests from a single IP (requests of any kind, and not only on a login page or form). Shared hostings often adopt policies of this kind in my knowledge and you generally do not have to worry too much about since you cannot change them. But if you have to configure a dedicated server this can be a bit more tricky: this is a subject for server administrators, more than web developers. If you use Apache, you could be interested in something like this: http://www.crucialp.com/resources/tutorials/server-administration/flood-protection-dos-ddos-protection-apache-1.3-2.0-mod_dosevasive-avoiding-denial-of-service-attacks.php

And: http://www.modsecurity.org/

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .