Created on 2017-08-13 00:40 by rouilj, last changed 2019-06-16 01:52 by rouilj.
|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|
|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.
|2019-06-16 01:52:10||rouilj||set||status: open -> fixed|
messages: + msg6547
|2019-06-07 20:39:30||rouilj||set||assignee: rouilj|
messages: + msg6538
|2019-05-12 20:08:16||rouilj||set||status: new -> open|
messages: + msg6471
messages: + msg6004
|2017-08-19 17:56:15||rouilj||set||messages: + msg6003|