Open ClaudiaMia opened 11 months ago
I think we could add a second factor, this could have a few options after the user presses login, the second factor will be requested, and password validity is only returned if both succeed
maybe captcha could be enforced to be set at least the 'after 3 failed attempts' option
another thing that could be considered is time-based IP ban, where after 10-50 invalid attempts the IP address will be banned for some period of time from login in, registering, or requesting a password change
Yes, requesting a captcha after 3 failed attempts with the same username in a certain amount of time, was what I basically suggested. After a successful login, the required captcha flag could be removed again from the affected account.
That we force the user to set up a 2nd factor via a token app or something like that is not a good idea I think. It is of course very secure, but it would be quite demanding of our users and I am not sure they would be willing to do so during registration.
Sending a 2nd factor code via email is not possible as we cannot contact users via e-mail unless they provide the email to us during the login, too. I think this would be possible as an alternative to solving a captcha after the x-th failed attempt or so.
I guess IP ban is too easy to circumvent? Hence my original suggestion of artificial login request processing limits based on small waits if the request is for the same username as well as not allowing parallel requests for the same username and limiting the amount of such requests we would queue for different users/IPs. But not sure if these measures are actually still needed if the captchas are enough of a roadblock and after some further failed attempts we ask for the email to send a code for every further attempt.
The flow to ask for the email and to input the code might be interesting to design though.
So if we imagine the user sent username and password and successful captcha solution for the maybe 10th time:
Hmm, I would like to suggest a lot simpler way to do it, that is just as effective: When we receive enough failed login attempts recently (e.g. more than 30 in the last 15 minutes; can be edited or even be scalable; counted globally across all accounts), then we give a captcha to everyone trying to log in.
Hmm, sure! I think that may be good enough for now if we also demand a minimum password length of maybe 8 characters.
If we later on see that this is triggered heavily and we see evidence that we may need more security, we can still implement other measures on top.
But I would not count all failed login attempts globally across all accounts, but I would say only if some account goes over the threshold of failed attempts for that username, we set that globally for some time or is that tricky to track per account over some time frame?
On the other hand, if we simply track number of failed attempts as a value per account as well as timestamp of last login attempt, then we can avoid bothering everyone with captchas, IF....
...if we change the login form to two steps: First only the username and only in the next screen the password.
That way we can enforce captchas per account.
Otherwise someone could make it a sport to ensure that captchas are requested all the time to annoy every user.
This is problematic, as it brings possibility of enumerating usernames - it is not that easy to implement this in a way that someone cannot test if username exists. Also browser password autocomplete doesn't really like this - while you can make it work and let it fill in the username and password one at a time, it also removes possibility of resident credentials autologin and makes it less convenient for users (they have to click button to continue twice, while their browser would have otherwise filled both at the same time on the first screen). Yes, there are other possibilities that makes this less of a problem, such as remembering username even if login token is no longer valid (so user that logged at least once always skips username entry, even if they need to log in again), but it is all about tradeoffs.
Hmm, I would like to suggest a lot simpler way to do it, that is just as effective: When we receive enough failed login attempts recently (e.g. more than 30 in the last 15 minutes; can be edited or even be scalable; counted globally across all accounts), then we give a captcha to everyone trying to log in.
Then I guess we are back to the above for now?
Separating user and password in separate forms is a no, we never want to give out any information based on the username alone
the way I would add this is login response with a list of 2nd factors the user needs to complete, this allows it to be extendable if we want, and would allow us to force captche globally if we want to if we deem that to many global attempts has been made, and same if it just for a single user
displayName
that Jomshir started to add should be standardized across all public interfaces so username
is no longer public, then a mechanism with at least a week time limit should be added that allows displayName
change
Ref: #505
Ref: #567
As for password strength I strongly advice against rules like "at least 8 characters" since it often does not lead to stronger passwords. Instead using a password strength estimator like zxcvbn is usually a way better option. It requires enough entropy and blocks commonly used words etc. "password" has 8 characters but is a very bad idea... and the library would catch that. Additionally it allows a life preview of password strength that can be displayed under the password field when chosing it.
TOTP I would also recommend as a very simple second factor.
For bruteforce protection I would recommend the standard exponential backoff on top of forcing captchas and forcing captchas globally if the ratio of success/attempts falls too low
As the username is known, the topic of making it too hard to guess passwords comes into focus.
For once, we should require a minimum password length of 8(?) characters.
Then I believe the server should artificially wait a random amount of milliseconds (maybe within the range of 1 and 4 seconds) while checking for a password and then maybe limit the amount of accepted parallel requests with the same username.
Unless we always ask for a captcha after 3 failed tries, we should maybe consider the following: After we detected that we had a large amount (30? 50? 100?) of failed login attempts with the same username within a certain amount of time, we switch the login form of Pandora globally to a different design for the next hour: The form would ask only for the username and providing it proceeds to a new page that prompts for the password separately. If the provided username was one of the usernames that received a large amount of failed login tries, we ask the user to solve a captcha from the start alongside the password input.