Welcome Guest, Not a member yet? Register   Sign In
Mitigate brute force attacks on login page
#1

[eluser]novice32[/eluser]
I just wanted to share the below for mitigating brute force attacks, which are often overlooked. Essentially, a valid login will get authenticated quickly, but an invalid will be delayed by 1 second.

Thoughts, anyone? I know you can block an IP after a number of failed attempts, but that seems risky and more complex.

Code:
function _login_valid()
    {

        $email = $this->input->post('email');
        $password = $this->input->post('password');
        if ($this->User_model->login_valid($email, $password) == false)
        {
            sleep(1); //if username and password combo is wrong, sleep for one second
            $this->form_validation->set_message('_login_valid', 'Invalid username and/or password.');
            return false;
        } else
        {
            return true;
        }
    }
#2

[eluser]theshiftexchange[/eluser]
[quote author="novice32" date="1334894356"]I just wanted to share the below for mitigating brute force attacks, which are often overlooked. Essentially, a valid login will get authenticated quickly, but an invalid will be delayed by 1 second.

Thoughts, anyone? I know you can block an IP after a number of failed attempts, but that seems risky and more complex.

Code:
function _login_valid()
    {

        $email = $this->input->post('email');
        $password = $this->input->post('password');
        if ($this->User_model->login_valid($email, $password) == false)
        {
            sleep(1); //if username and password combo is wrong, sleep for one second
            $this->form_validation->set_message('_login_valid', 'Invalid username and/or password.');
            return false;
        } else
        {
            return true;
        }
    }
[/quote]

That puts alot of strain on your server - and doesnt stop the brute force attack.

You could easily apply a couple of techniques
- block an IP after a number of failed attempts (very simple and easy to do), would stop the majority of attacks
- block a username after a number of failed attempts on that username (say 5-10). The user would be sent an email to unlock their account and reset their password

#3

[eluser]novice32[/eluser]
Thanks for your feedback. I know it's not the most optimal solution, but limiting to 1 request per second is way better than 9K-10k requests/second. I do, however, think it's the "cheapest" solution to "mitigate", and it's only 1 line of code!

For the process of blocking an IP, could you share a link code that easily do this? I see this a way more complicated since you'll need controller, model code, database table, and possibly a cron job unset blocked IPs after a certain duration.

In the 3rd option, that could be heavily disruptive to users. Imagine 200 users getting this emails on locked accounts or getting locked out - not nice, and I wouldn't want to try to explain to each of them.

Thanks again,
#4

[eluser]PhilTem[/eluser]
In case you add the sleep command to your code, the server isn't released from work since it's only sleeping and still processing the PHP interpreter's actions - which, in fact, is waiting. So there's still load on your server. It's really better to block IPs after too many wrong credentials.

Blocking IPs is really easy, since you already have a controller for the login page. Just add a check for any rows in your failed-logins-table where the IP matches and the record is not older than, let's say, 24h. If you find no rows the login form may be displayed, otherwise simply redirect to some other page of your desire.
#5

[eluser]CroNiX[/eluser]
People get 3 tries on passwords on my servers and then they get locked out by the firewall for 20 minutes for the first offense and then 24 hours for the second if it occurs within a 24 hour period. I use scripts that constantly monitor the php and apache error logs (and other logs) for bad login attempts and other risky activity. It's much better to block at the firewall level rather than the script level as they won't even be able to get to the script (or anything else on the server) after being blocked by the firewall. If you block at the script level I can just hit you over and over with multiple attempts and still be able to slow your app/server down with processing the requests, even if they ultimately get rejected.
#6

[eluser]skunkbad[/eluser]
[quote author="CroNiX" date="1334942781"]People get 3 tries on passwords on my servers and then they get locked out by the firewall for 20 minutes for the first offense and then 24 hours for the second if it occurs within a 24 hour period. I use scripts that constantly monitor the php and apache error logs (and other logs) for bad login attempts and other risky activity. It's much better to block at the firewall level rather than the script level as they won't even be able to get to the script (or anything else on the server) after being blocked by the firewall. If you block at the script level I can just hit you over and over with multiple attempts and still be able to slow your app/server down with processing the requests, even if they ultimately get rejected.[/quote]

Hey Steve,
I know you said you are updating the firewall, so that probably means you have your own servers. Do you think it is a viable solution to dynamically edit an .htaccess file with IPs to deny?
#7

[eluser]CroNiX[/eluser]
Yes, I've used that method as well and it is also better than addressing it in the script since it prevents it from reaching the script which means it will also consume fewer system resources.
#8

[eluser]skunkbad[/eluser]
Well, in terms of my current authentication system, I don't totally deny access, but instead allow them to see a lock-out message. In the case of a bot that is hammering away on the login, I think I may implement a solution such as denying by dynamic changes to the .htaccess. It would be easy to do, and I think you're right about lower system resources. I'd love to have my own server, but the only one I ever had was just a converted desktop computer, and I'm really not qualified to be a system admin.
#9

[eluser]CroNiX[/eluser]
If you did something like that I would make it a feature that can be turned on/off with an additional option to set the name (and path) of the .htaccess file. Not all hosts allow htaccess (most do) and some others even change the name of ".htaccess" to something else in the apache config (assuming they are using apache). If having .htaccess is a requirement for using community auth (a very nice app, BTW), then obviously this doesn't matter.
#10

[eluser]skunkbad[/eluser]
[quote author="CroNiX" date="1334950748"]If you did something like that I would make it a feature that can be turned on/off with an additional option to set the name (and path) of the .htaccess file. Not all hosts allow htaccess (most do) and some others even change the name of ".htaccess" to something else in the apache config (assuming they are using apache). If having .htaccess is a requirement for using community auth (a very nice app, BTW), then obviously this doesn't matter.[/quote]

Hey, thanks. Community Auth works 100% without .htaccess. I do like your ideas, and I have a few of my own. I'm going to have an Admin interface because I want them to be able able to add IPs to the banned list manually, and remove IPs if they need to. I wasn't aware of the issue with renaming .htaccess, and that the path could vary, which is good to know. Because of the way Community Auth logs in users, there really isn't ever a time when a real user would be able to submit the login form after being locked out, so my idea would be to instantly ban (for X amount of hours) any IP address that is associated with such a submission. I'm probably going to have to set up some sort of cron to check the dates of the banned IPs so that IPs can be released from being banned. Those are my initial thoughts. I'll probably start working on this in the next day or so.




Theme © iAndrew 2016 - Forum software by © MyBB