Roundup Tracker - Issues

Issue 2550949

classification
Rate limit password guesses/login attempts
Type: rfe Severity: normal
Components: Web interface Versions:
process
Status: fixed fixed
:
: rouilj : ber, rouilj
Priority: high : Effort-Medium, GSOC

Created on 2017-08-13 00:40 by rouilj, last changed 2019-06-16 01:52 by rouilj.

Messages
msg6002 Author: [hidden] (rouilj) Date: 2017-08-13 00:40
Currently an attacker can try to break an account password by trying
to login over and over again. It would be nice to implement a
mechanism that can make guessing a user's password more difficult/take
longer to accomplish.

While a web server that fronts Roundup can be configured to limit the
number of requests per ip, But this applies to all requests not just
login requests.

Problems: rate limiting can be used as a DOS mechanism for the account

Ideas: after some number of failed attempts (settable in the tracker
config) require a captcha/problem to be solved. E.G the login
page could display (example generated using figlet -W hello):

  _              _   _         
 | |__     ___  | | | |   ___  
 | '_ \   / _ \ | | | |  / _ \ 
 | | | | |  __/ | | | | | (_) |
 |_| |_|  \___| |_| |_|  \___/ 

and request that the user type it in along with their password.

Another idea is the user enters a password and there is a delay
before the server responds if the password is a failure. Maybe

   max(delay 3*(#failure - 3) * (#failures < 3), 30)

so under 3 failures no delay, over 3 failures increasing response
delay in 3 second increments to a max of 30s. This will slow down
1000 parallel connections to crack a user account so they get 1000/30s
rather than tens/hundreds of thousands/millions in 30s. It doesn't
have the accessibility issues of a capcha like mitigation.

Questions:

Can we update a failed_login counter in the user object and use that
to trigger mitigation. When the user finally logs in should this
notify the user that there have been N failed login attempts and then
reset the counter? Do we need more than a counter, e.g. record of
attempt and time stamp??

Need to make sure that an invalid username doesn't cause an issue.

Should we send the user to the password reset page automatically upon
exceeding the threshold?

What is the result of loss of accessibility? Maybe a randomly
generated question that is screen reader accessible would work
better. E.G: "Please enter the product of 10 and 11".

Should accounts with admin access have a more aggressive policy?
Could this allow the attacker to know that they have a powerful
account?

How to handle distributed brute force where attacker tries one
password against all user accounts? See (1) for ideas.


Other notes/resources:

https://timoh6.github.io/2015/05/07/Rate-limiting-web-application-login-attempts.html

https://www.drupal.org/node/485974 - discusses using rate limiting/ip.
But also some other discussion about problems/lockouts ...

https://stackoverflow.com/questions/549/the-definitive-guide-to-form-based-website-authentication
- see parts 6 and 7 - This recommends that delay not be in delaying the
  result of the check but in the ability to trigger a check. However I
  don't see how to do this without recording source ip and throttling/
  backing off based on the source of the request.

https://www.owasp.org/index.php/Authentication_Cheat_Sheet

https://stackoverflow.com/questions/479233/what-is-the-best-distributed-brute-force-countermeasure
(1)
msg6003 Author: [hidden] (rouilj) Date: 2017-08-19 17:56
one possible implementation:

http://www.roundup-tracker.org/cgi-bin/moin.cgi/RequireReCAPTCHAForLogin

uses Google reCAPTCHA. It is implemented as an extension that hooks
the login action. HTML needed for the login form and a
extensions/config.ini modification for activating and setting the
keys/site code needed by reCAPTCHA.

pro: uses recaptcha that should have a better II
cons: requires JavaScript which makes it unusable to most text based
browsers. while roundup does use JavaScript helpers, it can be used
without javascript with some enhancements missing. Being unable to login
however is more than a missing enhancement.

The plugin above doesn't really address the nonsense issue, but there
are recommendations on Google's web site on at least notifying the user
that they need js.
msg6004 Author: [hidden] (ber) Date: 2017-08-25 07:26
Hi John,
briefly checking the issue, I agree that it is an area that should be
improved.

As for using reCAPTCHA, there is an additional drawback that an external
connection is made which loses some information to the contacted server
and used network nodes.

So I'd prefer other solutions. 
Slowing down fast login-attempts seems the best to me.
Also adding some sort of captca or text-cha in case of several failed
login-attempts.

Another possible improvement could be to display the last login attempts,
so that a user may notice that an attack on her account is in progress.

The most effective counter measure would probably by logging failed attempts
and monitoring the log files and network logs for active intrusion attempts.
msg6471 Author: [hidden] (rouilj) Date: 2019-05-12 20:08
I implemented a rate limiting library as we probably need it for
the rest and xmlrpc interfaces. This is based on an existing gcra
algorithm I found.

As a test I implemented a limit of 3 web login attempts in 60 seconds.

The user can log in 3 times as fast as they want. On the 4th attempt
within a minute, they get a rejection with:

   Logins occurring too fast. Please wait: 20 seconds.

any attempts to log in during those 20 seconds will result in the same
message. The login attempt, even if it has the right password, is ignored.

After 20 seconds the user gets one login attempt and then is blocked for 20 
seconds again. If they wait for one minute they can try 3 more attempts.

There is a config setting to change the number of logins/minute.
The one minute interval is hard coded in LoginAction.

Committed on 5717:cad18de2b988. Note this broke a few tests because they
were tripping the rate limit. I managed to fix all of them except the
password migration/update test. I have set that to xfail at the moment as
I can't figure out how to fix it as it doesn't seem to be tripping the
rate limit test. Will ask for assistance on the devel list.
msg6538 Author: [hidden] (rouilj) Date: 2019-06-07 20:39
Bern, with the rate limit mechanism in place,
do you think this can be closed?

You suggested a textcaptcha after so many failed attempt
or logging all failed attempts and notifying the user.
That would require a different framework and also allows the
attacker to eat more resources than the rate limit solution does.

I have a couple more changes to make to rate limit: setting the
config value to 0 disables the rate limiting code, change
config to verify that integer value is not negative.

Also password migration/upgrade test is now passing (technically
xpassing). The xfail marker has been removed.

I have no clue what fixed this.

-- rouilj
msg6547 Author: [hidden] (rouilj) Date: 2019-06-16 01:52
Closing as fixed sufficiently.
History
Date User Action Args
2019-06-16 01:52:10rouiljsetstatus: open -> fixed
resolution: fixed
messages: + msg6547
2019-06-07 20:39:30rouiljsetassignee: rouilj
messages: + msg6538
2019-05-12 20:08:16rouiljsetstatus: new -> open
messages: + msg6471
2017-08-25 07:26:48bersetnosy: + ber
messages: + msg6004
2017-08-19 17:56:15rouiljsetmessages: + msg6003
2017-08-13 00:40:22rouiljcreate