EllisLab text mark
Advanced Search
1 of 2
1
   
Mitigate brute force attacks on login page
Posted: 19 April 2012 11:59 PM
Joined: 2010-03-01
72 posts

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.

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;
        
}
    } 
 
Posted: 20 April 2012 02:47 AM   [ # 1 ]   [ Rating: 0 ]
Avatar
Joined: 2009-05-05
241 posts
novice32 - 19 April 2012 11:59 PM

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.

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;
        
}
    } 

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

 

 
Posted: 20 April 2012 07:42 AM   [ # 2 ]   [ Rating: 0 ]
Joined: 2010-03-01
72 posts

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,

 
Posted: 20 April 2012 08:15 AM   [ # 3 ]   [ Rating: 0 ]
Joined: 2011-02-23
882 posts

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.

 Signature 

ignited Community Framework (WiP)  |  Read the User’s Guide. It won’t bite.

STOP! Before posting your questions, remember the WWW Golden rule:
What did you try? What did you get? What did you expect to get?

CI example .htaccess

 
Posted: 20 April 2012 01:26 PM   [ # 4 ]   [ Rating: 0 ]
Avatar
Joined: 2009-02-19
4326 posts

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.

 Signature 
 
Posted: 20 April 2012 01:50 PM   [ # 5 ]   [ Rating: 0 ]
Avatar
Joined: 2009-05-17
1433 posts
CroNiX - 20 April 2012 01:26 PM

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.

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?

 Signature 

Brian
Brian’s Web Design - Temecula
Community Auth - CodeIgniter Authentication Application

 
Posted: 20 April 2012 01:55 PM   [ # 6 ]   [ Rating: 0 ]
Avatar
Joined: 2009-02-19
4326 posts

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.

 Signature 
 
Posted: 20 April 2012 03:11 PM   [ # 7 ]   [ Rating: 0 ]
Avatar
Joined: 2009-05-17
1433 posts

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.

 Signature 

Brian
Brian’s Web Design - Temecula
Community Auth - CodeIgniter Authentication Application

 
Posted: 20 April 2012 03:39 PM   [ # 8 ]   [ Rating: 0 ]
Avatar
Joined: 2009-02-19
4326 posts

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.

 Signature 
 
Posted: 20 April 2012 06:24 PM   [ # 9 ]   [ Rating: 0 ]
Avatar
Joined: 2009-05-17
1433 posts
CroNiX - 20 April 2012 03:39 PM

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.

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.

 Signature 

Brian
Brian’s Web Design - Temecula
Community Auth - CodeIgniter Authentication Application

 
Posted: 22 April 2012 12:40 PM   [ # 10 ]   [ Rating: 0 ]
Joined: 2010-03-01
72 posts

Thanks guys for the feedback and suggestions. I’ll have to research more the different options. I have working SaaS application and won’t be able to easily integrate Community Auth. I’ll look at leveraging some of its code. In the end, it will be a home grown solution.

Another thought that came to mind is showing a captcha after a certain number of failed attempts. The captcha would be based on ip. With captcha, I wouldn’t need to lock accounts or anything of the sort.

Are there any good resources you could share regarding a captcha solution?

I’m thinking of blocking an IP and and displaying a captcha… say if there are more than 10 failed login requests / per IP.

Your thoughts?

 
Posted: 22 April 2012 02:53 PM   [ # 11 ]   [ Rating: 0 ]
Avatar
Joined: 2008-11-04
4489 posts

Not sure a captcha will protect you, it just means the attacker has to write a smarter script. You’ll have to mitigate server side.

I mitigate this by adding a delay before a second attempt to login can be made. The first few (configurable) are delay free, after that the delay is added, and the more attempts are being made, the longer the delay is.

After a (configurable) number of attempts the source IP is blacklisted and the delay is reset, to avoid this being used as a DDOS (you don’t want the legitimate users to be locked out of their own accounts).

 Signature 

Me: WanWizard.eu | My company: Exite | Datamapper: DataMapper ORM <= LOOKING FOR A NEW MAINTAINER!

 
Posted: 22 April 2012 03:23 PM   [ # 12 ]   [ Rating: 0 ]
Joined: 2010-03-01
72 posts

@WanWizard - how are you performing the delay (ie, php sleep(seconds);)?

 
Posted: 22 April 2012 04:09 PM   [ # 13 ]   [ Rating: 0 ]
Avatar
Joined: 2009-05-17
1433 posts

I did a bunch of work to Community Auth in the last couple of days, and part of what I did was to add functionality that adds an IP to a deny list in an .htaccess file after 10 unsuccessful logins. Under normal circumstances, meaning a human that is trying to login, they would only be allowed to get to 5 attempts before they are locked from further attempts for 10 minutes. If for some reason they keep attempting to login, perhaps by script, then they may achieve 10 unsuccessful logins, and they will get 403 Forbidden errors until an Admin goes in and clears it, or a certain amount of time has passed. I haven’t actually developed that last part yet, but I got to the point where the IP address is added to the htaccess file. The idea of denying somebody access by adding their IP to an htaccess file seems a little extreme, but it certainly handles the problem at the depth that I thought was reasonable for Community Auth, and reasonable for the majority of users. Yes, some people won’t have an .htaccess file, so this functionality will be allowed to be turned off (but I haven’t coded that up yet either). I’m hoping to have all of this done by next weekend.

 Signature 

Brian
Brian’s Web Design - Temecula
Community Auth - CodeIgniter Authentication Application

 
Posted: 23 April 2012 02:41 AM   [ # 14 ]   [ Rating: 0 ]
Avatar
Joined: 2008-11-04
4489 posts
novice32 - 22 April 2012 03:23 PM

@WanWizard - how are you performing the delay (ie, php sleep(seconds);)?

No, using a ‘flood control’ mechanism. So after a failed login, a new login will not be processed until “time() + delay” has passed.

 Signature 

Me: WanWizard.eu | My company: Exite | Datamapper: DataMapper ORM <= LOOKING FOR A NEW MAINTAINER!

 
Posted: 23 April 2012 05:45 AM   [ # 15 ]   [ Rating: 0 ]
Joined: 2012-04-22
2 posts

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.
i think so.

 
1 of 2
1