41

User registers account on a web app. Passwords are salted and hashed. But is it safe to check the password against the HIBP Pwned Passwords API, before salting and hashing it? Of course the app uses TLS.

So if the password is found on any breach - don't allow to register an account. If password not found in breach - salt it and store it in a database.

Same would apply if changing the password.

9
  • 1
    What do you mean by "is it safe to check the password against HIBP API"? If the check is sufficient?
    – Tom K.
    Mar 12, 2018 at 15:30
  • 8
    What value does this add for your users? Will registrants even have half a clue as to what pwned passwords are when you warn them of the futility of abc123? Even "safe" and KeePass'd passwords might have been pwned. Why not provide a password strength meter?
    – MonkeyZeus
    Mar 12, 2018 at 16:53
  • 11
    @MonkeyZeus because "Password123!" does pretty well on password strength meters (12 characters from four character classes), but is a crap password. It also doesn't meet NIST or NCSC guidelines, whereas checking HIBP would (at least, would be part of). Mar 12, 2018 at 20:48
  • 4
    @MartinBonner If a user is determined to be unsafe then they will be unsafe. If you try forcing them into safety then you better be providing a darn good service because they will stop using your service if it's too cumbersome. Password123$! is a presumably a strong but crap password as well but it has not been pwned. I am not saying that the HIBP is useless but OP's planned implementation will lead to frustration, forgotten passwords, sticky-note passwords, and flat out finding a different provider of the same service.
    – MonkeyZeus
    Mar 13, 2018 at 12:59
  • 1
    @MonkeyZeus The API returns the number of times a given password has been pwned, so you could set your system to only show a warning if the password had more than a given number of breaches. So you would be able to allow them to use a "safe" password that just happened to have been pwned once, while still using the API to block heavily pwned ones like "Password123!".
    – Spudley
    Mar 13, 2018 at 21:35

3 Answers 3

61

Have I Been Pwned? allows anyone to download the full database to perform the checks locally.

If that's not an option, using the API is safe, since it uses k-anonimity which allows you to perform the check without transmitting the full password / hash.

14
  • 12
    By no means does k-anonimity make something safe, especially when their k is somewhere in the hundreds. Few web pages prevent attackers from making a few hundred login attempts against an account.
    – Tgr
    Mar 13, 2018 at 6:17
  • 3
    The API doesn't use k-anonymity as it traditionally understood (which would be hard anyways since the set of all possible passwords is basically infinite). You request a hash prefix of length n and get 1/16^n of the whole database. So for the recommended n=5 and assuming one is fine with SHA-1 collisions, k would be ~ 1.4*10^42.
    – phihag
    Mar 13, 2018 at 7:10
  • 1
    @phihag With the recommended n=5 hex digits, that ends up leaking 20 bits of information on the password to HIBP (or whoever intercepts communication or compromises HIBP). That's a non-trivial information disclosure, especially considering the general quality of passwords.
    – marcelm
    Mar 13, 2018 at 12:50
  • 2
    Definitely go for the k-anonymity "search by range" option (haveibeenpwned.com/API/v2#SearchingPwnedPasswordsByRange). As for leaking information - does it really leak that much? You leak 20 bits of the hash but both "password" and "correct horse battery staple penguin jalopy car park" might have the same first five characters of the hash. If the user has a poor password then you'll find a match and tell them. If they don't have a poor password then you've still got LOTS of hashing to do to get five-char collisions.
    – IBBoard
    Mar 13, 2018 at 19:52
  • 1
    Um, no, k is number of hashes for which the service knows or can reasonably find out the corresponding password. If you take the claim of the service operator at face value, k ~= 400. But assume they know 100K more common passwords, which they kept secret, so the real k ~= 500. You check with the service until the user provides a password which passes, you create the account, the attackers associate the account with the call to the service based on timing, now they only have to try the account with the 100 passwords belonging to that hash prefix which they lied about.
    – Tgr
    Mar 13, 2018 at 20:28
15

As asked, No.

As of the posting of this answer, the question asks if it is safe to send a password "before salting and hashing it", which means in plaintext. You should never send a password in plaintext to a third party (second party may be OK if you are currently logging in). Even hashing the password is not enough, as a Rainbow Table can be used to look up the password. This is why when I saw someone (hashing and) sending every single password in a KeePass database to HIBP, I immediately called them out on it.

As other answers have pointed out, there is a new version of HIBP that includes k-anonymity (see that link and the other answers for more info). However, this is still divulging some information about the passwords (to HIBP, and any potential MITM attacker. Divulging some information is nowhere near as bad as leaking the entire password, but is still something you should be concerned about. What you really want is your passwords to be secure, not anonymous.

Ultimately, if you want to ensure that no information about your passwords is leaked in the checking process, you have to download the entire DataBase of pwned passwords, and hash and check your password locally (in this case, on the server because noone wants to download the entire DB just to create an account). Just don't store the password or the hash you are comparing to the DB anywhere, only store the salted hash in your actual password database.

1
  • 4
    Thank you. "Never send passwords to anyone" is the only sane approach. The other answers hemming and hawing over that question is terrifying.
    – jpmc26
    Mar 13, 2018 at 21:50
14

If the operator of the Pwned Passwords API is malicious (or the service is hacked by a malicious person, or someone intercepts your communication) it can lie about certain passwords (only return a subset of passwords it knows for that hash), record where the request came from, identify the website belonging to that ID, identify the account (based on creation time, for example) and test it with the passwords it lied about, for a decent chance of account compromise.

This is a fairly unlikely scenario (the owner of the API is a respectable security professional, the list of known hashes is public, and doing this kind of attack without being detected would be hard), so it depends on how risk-averse you are. If you run a discussion board, using the API is definitely a good idea. If you run an e-bank, maybe not so much.

Downloading the database and doing the checks locally is of course safer, but not a trivial task, given the size.

5
  • 8
    What, you think banks should be more secure than forums? That's not how the world currently works...
    – NH.
    Mar 13, 2018 at 19:47
  • I agree with this answer much more than the top voted one, but I felt I had to downvote because you didn't just come down hard on sending passwords around to 3rd party services.
    – jpmc26
    Mar 13, 2018 at 21:55
  • 3
    @jpmc26 security is always about tradeoffs. Someone running their web blog or discussion board with neither the time or expertise to implement server-side checking for known passwords will be far better off using the API. Troy Hunt going evil / getting hacked is a very small risk. Half your users reusing their passwords and not changing them after some of the sites hosting their other accounts have been hacked is almost a certainty.
    – Tgr
    Mar 14, 2018 at 2:56
  • 3
    @Tgr Exposing someone's bank password because they happened to use it on your blog and your blog sent the password to some third party service is never acceptable.
    – jpmc26
    Mar 14, 2018 at 3:04
  • 2
    If you reuse your bank password on random weblogs, it's only a matter of time until it gets cracked, whether or not those sites share it. Also if it is a strong password (although who would pick a strong password and then reuse it between a critical service and a random website), the attacker is in no way helped by learning the few first characters of the hash. On the other hand, you are certainly right that it violates user expectations...
    – Tgr
    Mar 14, 2018 at 3:13

You must log in to answer this question.

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