librelist archives

« back to archive

Protecting user passwords from dictionary attacks

Protecting user passwords from dictionary attacks

From:
Jóan Petur Petersen
Date:
2013-12-29 @ 18:09
Hi everyone,

I’m new to flask and web development. I’ve started making a skeleton for a
login system with MongoDB as a backend. The idea is that it should be
secure skeleton to start from. The code so far is here:
https://github.com/JoanPeturPetersen/mongoflask-skeleton

However I have had trouble finding a good solution for protecting the login
page from dictionary attacks or similar. The solution implemented now only
measures the time between login attempts for a username. The last login
attempt time is stored in the user’s record in the database based upon the
username used to try to log in with. If too little time has passed since
the last attempt, then the user will just be taken back to the login page,
and presented with a message that he/she has to wait. This approach is not
so good, because if someone continuously tries to guess the password for a
username, the real user with that username can get locked out from of
system - kind of a denial of service attack.

I would like to avoid tracking the IP addresses from which users try to log
in, as it can potentially be a very large data set. Also this wouldn’t help
if the hacker is trying to guess the password from several IP addresses
using proxies, bots, or something in that style.

To improve on this system, I though of instead of having the user to wait
before being allowed to try again, the user would be presented with a
reCAPTCHA question, which should be answered correctly before the system
evaluates the username/password pair.

Someone also suggested to me, that the application just waits/sleeps a
while, maybe one second, before evaluating a username and password pair.
This would limit the number of password tried. However I have a feeling
that there might also be some problems with this solution, as the server
resources would be occupied for this time? And this could result in a
denial of service for all users in the end, if enough connections are
waiting?

What are your thoughts on this? How would you protect the users passwords
against a dictionary attack on the login page?

Thank you, and a happy new year :)
Jóan Petur

Re: [flask] Protecting user passwords from dictionary attacks

From:
Patrick Schmid
Date:
2013-12-29 @ 18:14
You can always lock the user account after n failed attempts in a given
window...

Patrick
On Dec 29, 2013 1:12 PM, "Jóan Petur Petersen" <joanpeturpetersen@gmail.com>
wrote:

>
> Hi everyone,
>
> I’m new to flask and web development. I’ve started making a skeleton for a
> login system with MongoDB as a backend. The idea is that it should be
> secure skeleton to start from. The code so far is here:
> https://github.com/JoanPeturPetersen/mongoflask-skeleton
>
> However I have had trouble finding a good solution for protecting the
> login page from dictionary attacks or similar. The solution implemented now
> only measures the time between login attempts for a username. The last
> login attempt time is stored in the user’s record in the database based
> upon the username used to try to log in with. If too little time has passed
> since the last attempt, then the user will just be taken back to the login
> page, and presented with a message that he/she has to wait. This approach
> is not so good, because if someone continuously tries to guess the password
> for a username, the real user with that username can get locked out from of
> system - kind of a denial of service attack.
>
> I would like to avoid tracking the IP addresses from which users try to
> log in, as it can potentially be a very large data set. Also this wouldn’t
> help if the hacker is trying to guess the password from several IP
> addresses using proxies, bots, or something in that style.
>
> To improve on this system, I though of instead of having the user to wait
> before being allowed to try again, the user would be presented with a
> reCAPTCHA question, which should be answered correctly before the system
> evaluates the username/password pair.
>
> Someone also suggested to me, that the application just waits/sleeps a
> while, maybe one second, before evaluating a username and password pair.
> This would limit the number of password tried. However I have a feeling
> that there might also be some problems with this solution, as the server
> resources would be occupied for this time? And this could result in a
> denial of service for all users in the end, if enough connections are
> waiting?
>
> What are your thoughts on this? How would you protect the users passwords
> against a dictionary attack on the login page?
>
> Thank you, and a happy new year :)
> Jóan Petur
>
>

Re: [flask] Protecting user passwords from dictionary attacks

From:
Emanuil Tolev
Date:
2013-12-29 @ 18:37
Flask-WTForms supports Recaptcha for a really easy integration:
https://flask-wtf.readthedocs.org/en/latest/form.html#recaptcha , including
making it succeed each time if DEBUG (and/or some other config var, can't
remember) is True. That seems like a good solution.

If you're approaching this from a "we want to do it as best as possible"
angle, I'd go for the captcha after X failed attempts rather than lock the
account. (Since I can lock somebody else's account or any number of
accounts just by being stupid with a script.)

The waiting-on-fail solution is kind-of the typical security way to solve
this AFAIK (c.f. your normal *nix PAM auth). And I believe you're right in
thinking sleep will block your web app's thread. So, could you make the web
server delay its response instead of blocking the web app's thread with a
sleep instruction?
E.g. nginx can do non-blocking sleep (just that particular worker gets
delayed as far as I understand it):
http://wiki.nginx.org/HttpEchoModule#echo_sleep

nginx is going to be faster than your app's thread .. though of course it
will also have to wait the full 0.5 or 1 seconds. That smells of breaking
nginx's famous ability to handle lots of concurrent requests, and could
make it more vulnerable to DoS.

So, then you could control the number of workers who exhibit this behaviour
(this part I'm not sure how to configure!). Basically only allocate, say,
25% of nginx workers to serve failed login attempts (and serve other things
when there are no such attempts).

This is much more convoluted than a reCaptcha though :). I'm only including
the info since I thought it was interesting to see if you could make nginx
do this, I wouldn't really try it for a production app.

Greetings,
Emanuil


On 29 December 2013 18:09, Jóan Petur Petersen
<joanpeturpetersen@gmail.com>wrote:

>
> Hi everyone,
>
> I’m new to flask and web development. I’ve started making a skeleton for a
> login system with MongoDB as a backend. The idea is that it should be
> secure skeleton to start from. The code so far is here:
> https://github.com/JoanPeturPetersen/mongoflask-skeleton
>
> However I have had trouble finding a good solution for protecting the
> login page from dictionary attacks or similar. The solution implemented now
> only measures the time between login attempts for a username. The last
> login attempt time is stored in the user’s record in the database based
> upon the username used to try to log in with. If too little time has passed
> since the last attempt, then the user will just be taken back to the login
> page, and presented with a message that he/she has to wait. This approach
> is not so good, because if someone continuously tries to guess the password
> for a username, the real user with that username can get locked out from of
> system - kind of a denial of service attack.
>
> I would like to avoid tracking the IP addresses from which users try to
> log in, as it can potentially be a very large data set. Also this wouldn’t
> help if the hacker is trying to guess the password from several IP
> addresses using proxies, bots, or something in that style.
>
> To improve on this system, I though of instead of having the user to wait
> before being allowed to try again, the user would be presented with a
> reCAPTCHA question, which should be answered correctly before the system
> evaluates the username/password pair.
>
> Someone also suggested to me, that the application just waits/sleeps a
> while, maybe one second, before evaluating a username and password pair.
> This would limit the number of password tried. However I have a feeling
> that there might also be some problems with this solution, as the server
> resources would be occupied for this time? And this could result in a
> denial of service for all users in the end, if enough connections are
> waiting?
>
> What are your thoughts on this? How would you protect the users passwords
> against a dictionary attack on the login page?
>
> Thank you, and a happy new year :)
> Jóan Petur
>
>