English 中文(简体)
Brute-force/DoS prevention in PHP [closed]
原标题:
Closed. This question needs details or clarity. It is not currently accepting answers.

Want to improve this question? Add details and clarify the problem by editing this post.

Closed 2 years ago.

I am trying to write a script to prevent brute-force login attempts in a website I m building. The logic goes something like this:

  1. User sends login information.
  2. Check if username and password is correct
    • If Yes, let them in.
    • If No, record a failed attempt in the database. Check if there s too many fails within a given timeframe (eg: 5 in 5 minutes):
      • If Yes, then pause execution for 10 seconds: sleep(10), then report a login failure to the user.
      • Report a login failure to the user immediately

Explaining this to a co-worker, I was asked how this would help if a hacker sent, say, 1000 requests in one second. Would the first 5 would return immediately, and then the remaining 995 all take only 10 seconds?

I have a sneaking suspicion that I don t fully understand how HTTP works - is that situation above even possible, or is there a limit to the number of concurrent requests that a server will handle from one client?

Would a better solution be to have an increasing sleep time?

sleep($numRequestsInLast5Minutes - 5)

So the first 5 would be fast, and then every subsequent one would increase the sleep.

问题回答

The problem is the balance between user accessibility and attacker model.

First Solution

If not password correct for a certain number of time:
    block the user
    send a reset link to the user

User: could be blocked, and they don t like to reset
Attacker: blocked all users by trying to authenticate to all users (especially if all logins are publicly available)

Second solution

If not password correct:
    sleep(amount_of_time)

The question is: what is the value of amount_of_time ?

User: can be annoying to wait amount_of_time for each error
Attacker: keep trying, with lower test / seconds

Third Solution

If not password correct:
    sleep(amount_of_time)
    amount_of_time = amount_of_time * 2

User: less annoying for few password mistakes
Attacker: block the user to connect by sending lot of incorrect password

Fourth Solution

If not password correct for a certain number of time:
    submit a CAPTCHA

User: need to resolve the CAPTCHA (not too complex)
Attacker: need to resolve the CAPTCHA (must be complex)

Good solution (and used by a lot of sites) but be careful to our CAPTCHA. implementation. Anyway there is a trick (see next solution).

Fifth Solution

If not password correct for a certain number of time:
    block the IP
    (eventually) send a reset link

User: User may be blocked because he cannot correctly remember his password.
Attacker: trying the same password with different user, because blocking is based on number of login by user.

Final Solution ?

If several login attempts failed whatever is the user by an IP :
    print a CAPTCHA for this IP

User: User cannot be IP blocked but must remember its password.
Attacker: difficult to have an efficient brute-force attack.

The important notes

Is the login form or the login submit link which is blocked ? Blocking the login form is useless.

Resistance to brute-force is FIRST a problem of password complexity, so you need a strict password policy (especially in the case of distributed brute force).

I don t mention the fact to hash your passwords with salt, you re already doing this right ? Because if it is easier to access to the password database than brute-forcing, the attacker will choose this solution ("A chain is only as strong as its weakest link").

I would suggest if the user has tried unsuccessfully, say more than five times and five minutes, you start returning a 503 Service Unavailable immediately, for that IP address. When a login fails, you could use memcache to get the current bad attempts for an IP, and then increment the amount, and save it back to memcache with a 5 minute expiry.

You don t want to put a sleep in your PHP code, as that will allow a single user to create lots of connections to your web server, and potentially bring down other users.

Since the user hasn t logged in, you don t have a session cookie, and if the user is trying to brute force their way into an account, they may not present a cookie at all.

I have used something like this...

  1. Check username and password

    1.1 If no match then, record last failed login time for that combo and number of failed logins.

    1.2 Each fail makes the wait between being able to login something like failsCount * 30 seconds, up to a maximum (such as 10 minutes).

  • This means a brute force attack will exponentially take longer and longer.
  • It could lock a user out - but it will not count a failed login whilst trying to login during the lockout period. This should minimise it.

I ve developed this but not released it into the wild yet, so any feedback would be appreciated.

I made a class that takes care of brute force attack protection in PHP.

https://github.com/ejfrancis/BruteForceBlocker

it logs all failed logins site-wide in a db table, and if the number of failed logins in the last 10 minutes (or whatever time frame you choose) is over a set limit, it enforces a time delay and/or a captcha requirement before logging in again.

example:

//build throttle settings array. (# recent failed logins => response).

$throttle_settings = [

    50 => 2,            //delay in seconds
    150 => 4,           //delay in seconds
    300 =>  captcha     //captcha 

];

$BFBresponse = BruteForceBlocker::getLoginStatus($throttle_settings);

//$throttle_settings is an optional parameter. if it s not included,the default settings array in BruteForceBlocker.php will be used

switch ($BFBresponse[ status ]){

case  safe :
    //safe to login
    break;
case  error :
    //error occured. get message
    $error_message = $BFBresponse[ message ];
    break;
case  delay :
    //time delay required before next login
    $remaining_delay_in_seconds = $BFBresponse[ message ];
    break;
case  captcha :
    //captcha required
    break;

}

I am not sure what the best practice is, but when dealing with DoS attacks, a better strategy is to actually divert traffic away from your server. Setting timeouts won t actually help because you re still processing the request and running PHP.

Have you considered setting up another web server running a simpler stripped down version of your login page? When the user tries too many times (e.g., thousands of times), send a message to configure your router and redirect this user to the second web server.

It s like when websites get hit with the slashdot effect, many of them just redirect traffic away until traffic is reduced.





相关问题
Signed executables under Linux

For security reasons, it is desirable to check the integrity of code before execution, avoiding tampered software by an attacker. So, my question is How to sign executable code and run only trusted ...

MALICIOUS_CODE EI_EXPOSE_REP Medium

I run findbugs against all of my code and only tackle the top stuff. I finally got the top stuff resolved and now am looking at the details. I have a simple entity, say a user: public class User ...

XSS on jsbin.com

Anyone know if jsbin.com implements any protection for XSS or other javascript attacks? I see jsbin links used fairly regularly on sites like this one and I can t find any indication from the site ...

Make md5 strong

Im making a website that will intergrate with game that only support md5 hashing metod (atm). Which ofc is not especially safe anymore. But how could i make it stronger? Should I just generate long ...

Why running a service as Local System is bad on windows?

I am trying to find out the difference between difference service account types. I tumbled upon this question. The answer was because it has powerful access to local resources, and Network Service ...

Brute-force/DoS prevention in PHP [closed]

I am trying to write a script to prevent brute-force login attempts in a website I m building. The logic goes something like this: User sends login information. Check if username and password is ...

热门标签