16

Best practices say that when users choose a password (at signup or when changing an existing password), the application should reject that password if it appears on a list of passwords known to be unsafe. For example, NIST Special Publication 800-63 from 2017 says the following (emphasis mine):

When processing requests to establish and change memorized secrets, verifiers SHALL compare the prospective secrets against a list that contains values known to be commonly-used, expected, or compromised. For example, the list MAY include, but is not limited to:

  • Passwords obtained from previous breach corpuses.
  • Dictionary words.
  • Repetitive or sequential characters (e.g. ‘aaaaaa’, ‘1234abcd’).
  • Context-specific words, such as the name of the service, the username, and derivatives thereof.

If the chosen secret is found in the list, the CSP or verifier SHALL advise the subscriber that they need to select a different secret, SHALL provide the reason for rejection, and SHALL require the subscriber to choose a different value.

Let's say I implement this using Have I Been Pwned's "Pwned Passwords" API.

Now what happens if a password used by one or more of my users appears¹ in a data breach? Obviously, the password should now be considered "definitely unsafe"²: sooner or later, attackers will include that password in credential stuffing or password spraying attacks.

Following the NIST advice, my application would reject entering such a password on a "change password" form (see above: "When processing requests to (...) change memorized secrets, verifiers SHALL (...)").

However, if nobody was alerted of that particular password being breached (neither me as the application owner nor every user using that password), that alone will not help: Attackers can still use that password until affected users have changed their password. But that may or may not happen. What's worse, for seldomly-used applications, a lot of time may pass until they log in the next time, so simply displaying a warning on login will not shorten the attack window.

Therefore, I believe that my application should reject login attempts which use a breached password:

  • That way, an affected account would effectively be locked from the moment its password appears in a breach corpus. As no attacker could gain access, breach corpus passwords become useless to attackers.³
  • The application would reject the login attempt with the same reaction (visible message and API response) as if the wrong password was used. This avoids giving the attacker the potentially useful information that this username/password could be used elsewhere.
  • When a login attempt is rejected due to this, the application could send an email to the account owner informing them of the situation and asking them to use "reset password" functionality. The email would be sent asynchronously to minimize the risk of timing-based information leakage.
  • To avoid repeated emails, the application would also set an appropriate flag on the account.

What I tried

I could not find any mention of rejecting login attempts related to breach corpuses. I thought about whether the word "establish" in the NIST guideline could mean "login", but I doubt that as the rest of that section would not really fit that interpretation.

When processing requests to establish and change memorized secrets, verifiers SHALL compare the prospective secrets (...)

Questions

  1. Is there any official/established/popular advice on the topic of rejecting login attempts due to passwords occuring in breach corpuses (as opposed to rejecting password change attempts)?
  2. Is such an approach advisable in general?
  3. Does this (my approach outlined above or the general idea) have any drawbacks or caveats one should consider?

Footnotes

  1. For this, it doesn't matter whether it was indeed my user's data or someone else's data that appeared in the breach.

  2. I am aware that just because a password does not appear on breach corpuses, it does not mean it should be considered safe.

  3. Only the most fresh breaches, the ones that did not yet make it to HIBP, would still be useful.

13
  • 8
    Caveat: your users will get frustrated and use something like the browser's default autofill password, or save it in a text file so they remember, which comes with its own security concerns. There's a constant conflict between security and usability.
    – belkarx
    Commented Oct 5, 2022 at 17:35
  • 11
    @belkarx I know I get especially frustrated when a site rejects my password and I know it's right because it came from the $#@! autofill because there's no way the password is wrong and thus the site is lying for some reason and if there's one thing I can't tolerate it's a machine lying...
    – Michael
    Commented Oct 6, 2022 at 15:45
  • 3
    If you're going to go this far, why not go all the way and automatically e-mail the user the moment their password is published in a breach corpus, instead of waiting for them to log in? While the asynchronous e-mail is nice, it also introduces a delay which can create frustration for a user who needs to log in now.
    – Michael
    Commented Oct 6, 2022 at 15:46
  • 4
    @Michael: An application should not be persisting passwords, but rather, should only persist the result of hashing passwords with bcrypt or similar; and Have I Been Pwned (HIBP) doesn't vend the actual passwords found in a data breach, only their SHA-1 and NTLM hashes. As a result, an application can only check a password against HIBP when that password is provided to it, e.g. at login time.
    – ruakh
    Commented Oct 6, 2022 at 19:19
  • 3
    @belkarx: Wait, what's wrong with using the browser's default autofill password? I would have thought that it's a good thing if users use that!
    – ruakh
    Commented Oct 6, 2022 at 19:20

4 Answers 4

19

There is no single right choice, i.e. it depends on the details of your actual use case, as often it is a trade-off between usability and security. Some aspects to consider:

  • If the account is valuable to the user, then the user might actually be thankful for this protection. But in the other case, you might lose a customer, i.e. lost value for you.
  • If lots of damage might be done with the account it is important to you as a service to protect the account, so blocking the account might be acceptable even if it might mean losing users.
  • There might be less severe options to fully blocking the account immediately, like limiting what can be done with it. This is more usable for the customer, so you might keep the customer while still protecting them.
  • Given that passwords are often reused, it might not be safe to trust the user's email for password resets, since the email account might be compromised too. So you might need to employ more secure identity verification, which will result in even less usability for the user.
  • You might actually be overwhelmed with users contacting your support, so be careful when enabling this protection for all users at once.
  • Also be very careful on how you communicate to the user the reason for the password reset. It could be easily misinterpreted as a password leak on your side, which would be bad PR for you.

There is actual research into this topic, like this project (sorry, only in German - but there are also some academic papers in English linked). The points above are based on information I got from people involved in this research project.

6
  • It's too bad you can't do it the old school way of "send the user to password change immediately" anymore.
    – Joshua
    Commented Oct 6, 2022 at 16:18
  • 2
    @Joshua: You cannot do this since you can't be sure that it is actually the user logging in and not already some attacker misusing the known password. Because in this case the attacker could simply change the password to something new - and thus keep access to the account while locking out the user. This result would likely be the worst. Commented Oct 6, 2022 at 16:36
  • Well obviously you should try logging into the users email account with the password before sending them the email. Problem solved.
    – DonQuiKong
    Commented Oct 8, 2022 at 7:17
  • 3
    @DonQuiKong: "Problem solved." - not really. First, it might legally not a good idea trying to login into an account which does not belong to you. Then, not all mail accounts get logged in by using the email as a username, sometimes it is a different username. Then, you can at most check that this particular password was not used with the account, not that some other known and weak password was used. Commented Oct 8, 2022 at 7:24
  • 1
    @DonQuiKong: That is a criminal action and I would seriously think about trying to bring criminal charges against any company that attempted logins to my email based on a password I gave them. Absolutely, NEVER attempt to login to an email account that is not yours and that you do not have the owner's clear permission and genuine consent (not compelled) to log in to. Commented Oct 8, 2022 at 15:22
11

What is your threat model - how much damage can be done with a compromised account?

The best option, if you do have an additional/stronger authentication method, like 2FA or biometric, is to suspend high-impact operations until the user reauthenticates with said stronger method.

For an app that can do financial damage to the user, this should already be built-in. For apps that combine financial and non-financial services, it's good practice to have two levels of authentication, for read-only access and for transactions.

As a general rule, for anything unimportant enough to only be protected by a password, denying access in the event of a weakened password is not normal practice. This is driven by the same usability considerations that have led to the decision to rely on weak authentication (password only) in the first place.

For anything important, your 2FA should be a stronger temporary protection than email-based password reset, as the second factor is more independent than email and site password.

For very high security scenarios, you may want to make use of this marginal bit of security, the hope that the email is safe. But 3FA (like third-party biometric verification) is a stronger security guarantee still, so again makes the extra security from the email password insignificant.

6

I would advocate against rejecting the login attempt. That would be giving the wrong signal to the user.

Much better to communicate it without disabling their account. But do add a banner with information for the user. With a link to explain what you found and what that means.

Basically we want to give the users the feeling we are there to protect them… and not there to make them do things we want.

4
  • 1
    But, as Steffen, outlines, sometimes the risks outweigh the convenience and potential messaging. It needs to be weighed, and not a hard-and-fast rule either way.
    – schroeder
    Commented Oct 6, 2022 at 9:54
  • 13
    If it's my Bank I want my account locked, if it's a random hobby site not so bothered.
    – deep64blue
    Commented Oct 6, 2022 at 11:08
  • 1
    @deep64blue Do you have a bank account where the entire protection consists of a password to be entered from any computer? If so, switch your bank immediately. If the bank uses some kind of two-factor identification and one factor is the low quality password, the bank should tell me to change the password but I don't want my account locked.
    – quarague
    Commented Oct 7, 2022 at 9:02
  • @deep64blue: If it's my bank, I don't want the login to let someone do anything more than read my bank statements and make internal transfers between my accounts... Commented Oct 8, 2022 at 15:24
4

Remember that availability is a security requirement. If you are a bank and your security policy prevents a customer from paying his rent, that is a failure of your security policy. Of course there are tradeoffs, but you have to at least consider a hit to availability as something to be avoided. The appropriate balance depends on the risks.

For this, it doesn't matter whether it was indeed my user's data or someone else's data that appeared in the breach.

I'd suggest that is actually not true. If it is someone else's data, the response you suggest would almost certainly be disproportionate. There is no reason to expect that an attacker would associate that new, and presumably very rare, leaked password with this account. They'd be more likely to try "Password" or "monkey" just because that has a better expectation of success. Even if they're only trying new leaks, you'd expect to notice them trying many thousands (or, ten and then you block them) of newly leaked passwords before getting close.

On the other hand if the password leak was associated with the individual, none of that works. If the attacker has the password paired with an identity (e.g. an email address) then it goes straight to the top of their attempt list. You couldn't expect any warning shots. As such, locking them out and contacting them out-of-band to verify their identity and reset their authentication is exactly what you would have to do.

If you don't know which case is which, you can make a probabilistic risk argument in favour of treating it as serious. Just remember to count the cost to availability and develop a smooth recovery process.

8
  • 1
    "There is no reason to expect that an attacker would associate that new, and presumably very rare, leaked password with this account." - That's true. But as I mentioned in the question, this is about credential stuffing or password spraying attacks. AFAIU, it's this kind of attacks that the original advice "at signup, reject widely known passwords" is intended to battle. And if I do that, why should I limit that to signup (and password change)? IMO, the attack surface to a user account will be the same when their password appears in a breach later. Commented Oct 7, 2022 at 18:11
  • The danger hasn't changed, but the cost of the proposed enforcement may be much higher. Either could shift the risk/reward calculation.
    – Josiah
    Commented Oct 7, 2022 at 19:32
  • 1
    Sorry, I was unclear. I don't mean that it is no more risky after the leak than before the leak. I mean that, given a pair of people one who had already set the newly leaked password and the other who is just about to, neither is more at risk than the other. The reason for allowing the former to keep hers and forbidding the latter to set his would be entirely down to the cost of the intervention.
    – Josiah
    Commented Oct 7, 2022 at 20:05
  • 2
    This sparked an interesting idea in my head: we would not have to guess the cost of the intervention (i.e. whether the legitimate user appreciates being locked out) if the app actually asked the user in advance (at signup) which behavior they would prefer. As usual, adding such a feature should be weighed carefully to avoid Feature creep. Also, when the intervention occurs, the user might not remember that they actually chose this option, so the email message should be worded carefully. Commented Oct 8, 2022 at 7:37
  • 3
    What @JensBannmann said is so important. Different users have different security and availability requirements, and some fundamentally do not have, and cannot have, additional factors to authenticate with (refugees, homeless, children of abusive parents, people with abusive partners, etc.). You need to ask the user what their needs are in securing their account and which outcomes they consider acceptable. Commented Oct 8, 2022 at 15:27

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .