8

Currently my project still uses MD5 hashing to encrypt passwords. Yeah, I know.

I'm planning to update the password system to use the newer password_hash and password_verify functions in PHP, which will improve the security of the users' passwords.

However, my moderator team has voiced a concern: since one of our core rules prohibits users from having more than one account, they need ways to tell if two accounts belong to the same person. One such way that they have used is to check if the MD5 hashes are the same on the two suspect accounts - if so, then the accounts have the same password and suspicion intensifies. But with the proposed new system, this will no longer be possible because different hashes will be produced on the two accounts.

In the interest of finding a compromise, is there any way to use the better security of password_hash, while still providing a way for the moderator team to detect when two accounts share the same password?

My thoughts at the moment involve hashing the password in some other way that will produce the same hash for the same password, but I'm worried that this will re-introduce the same vulnerability that we're trying to escape by moving away from MD5. Are there any options here or will I have to use Executive Decision Power to overrule the concern?

6
  • 23
    I'd suggest you use alternate mechanisms of duplicate account detection. You can use items like source IP address and browser agent to start finger-printing users pretty well as a means of identifying duplicate accounts. If you don't mind users possibly thinking of you as creepy there's also some panopticlick style libs out there I believe that do a good job of fingerprinting clients pretty accuarately. Commented Nov 20, 2015 at 12:06
  • 21
    So much wrong with this scenario. (1.) You shouldn't be using MD5 for passwords, but you already knew that. (2.) If you can tell two passwords are the same by comparing hashes, then you're not salting. Also very bad. (3.) You've got too many users with access to the password hashes. Unless they're also handling database/system administration or development of your application, moderators have no good reason to have access to the passwords in any form. And, for the most part, even if they were doing those tasks they still shouldn't be using their access deliberately to analyze passwords.
    – Iszi
    Commented Nov 20, 2015 at 17:33
  • 5
    (4.) Without knowing the cleartext - which they generally should have even less reason to know than the hashes - your moderators have no way of knowing whether or not password duplication across multiple users is a reliable indicator of sockpuppet accounts. Numerous leaks of massive password databases have shown that a significant percentage of unique individuals share the same (or very similar) password.
    – Iszi
    Commented Nov 20, 2015 at 17:33
  • 6
    Multiple accounts using "password" is not at all noteworthy for your purposes here. Multiple accounts using "v47moiODzM5aJ" just might be. But, with proper password storage, neither your moderators nor even you should be able to tell whether any two users' password hashes represent the same password - let alone what they actually are.
    – Iszi
    Commented Nov 20, 2015 at 17:35
  • Comments are not for extended discussion; this conversation has been moved to chat.
    – Rory Alsop
    Commented Nov 20, 2015 at 19:01

4 Answers 4

39

One of the reasons that password_hash produces different results for the same password is to prevent information leaks and make passwords harder to crack if the hashes are obtained by an attacker. You really don't want to compromise this security feature - not only will it be less protection for customer data but you will also be rolling your own solution rather than using well supported and accepted solutions.

Using identical password to detect multiple accounts by the same account holder is a bad idea anyway - it is bound to cause false positives and result in you blocking legitimate accounts.

2
21

The X Y Problem

What you have is the classic X Y Problem (xyproblem.info). You want to keep users from having multiple accounts, and mistakenly think that implementing a broken password system and comparing hashes will help you solve this problem. So you asked how to detect identical passwords. As @Ggd's answer described, attempting this causes false positives, is easily circumvented, and forces you to throw out tried-and-true password-handling practices.

Solving your Real Problem

Your actual question-behind-the-question is "How do I keep users from having multiple accounts?". This question has been asked before. However one question is from 2008 and even mentions "Accounts with same password" as a factor for mitigation, and the other didn't go into sufficient detail/options, so it seems that this issue should be revisited.

As you and your company have already discovered, there is no simple and foolproof solution for this. What you can do is have a smart multi-front effort to minimize the problem. Valid checks include:

  • IP logging: This can create false positives for groups sharing a single public-facing IP as well as be avoided by using proxies, tor, or DHCP requests. It can, however, be a good first step in investigating the possibility.
  • Email verification: Requiring the user to provide and click through an email verification is another valid, but easily routed-around, check.
  • Mobile phone verification: similar to email, but require validation via SMS on either sign-up (less intrusive) or login (more intrusive, possible DoS if phone/signal not available).
  • Follow the money: Require a credit card or link to a valid PayPal (or other service) account. Possibly perform a micro-transaction and request the details to prove the account is in the control of the user.
  • Domain-specific credential: Is there a certification required for the user base (for example, a site for Registered Nurses could require a valid License number)?

Practical solutions to your problem will no doubt require a balance. You don't want to discourage users with too high a barrier to entry, unless you are more concerned with "one person, one account" than growth and traction. You DEFINITELY don't want to endanger your users' account security with a bad password system as part of this trade-off: the legal, financial, and reputation costs of a breach far outweigh any (dubious) benefit.

4
  • 1
    Probably the only bullet item here that's not (relatively) easily subject to bypass is the domain-specific credential. SMS and credit card validation are a bit more inconvenient to work around, but still pretty easy to manage. E-mail and IP verification can be trivially side-stepped. Still, any of these are better than relying on password comparison.
    – Iszi
    Commented Nov 20, 2015 at 17:41
  • As for credit cards, can't you go buy a prepaid card in wal-mart or something? :) Commented Nov 20, 2015 at 18:26
  • @MarkHulkalo Certainly. But it's much easier and infinitely less expensive to just change your IP or e-mail address.
    – Iszi
    Commented Nov 20, 2015 at 19:31
  • @Iszi Agreed. Just pointing that out. Commented Nov 20, 2015 at 19:37
6

I would say there is a way to do it securely - based on this statement in your question:

One such way that they have used is to check if the MD5 hashes are the same on the two suspect accounts

What this is asking for is not a way to automatically identify any pair of accounts using the same password. You only need a way to decide whether a pair of accounts share the same password once there is already a suspicion.

Based on that I would solve the problem like this:

  1. Store the password securely using a salted hash.
  2. Create an additional table listing pairs of accounts suspected to be using the same password, and a status for each pair.
  3. When a pair is suspected to be using the same password insert it into the suspect table with status set to unknown.
  4. After each successful login search for the user in the suspected table.
  5. If the user is found in the suspected table test the password against the other user in that pair. If status is unknown change it to either identical or different.

Of course as others have pointed out, the password being identical is only one signal of many. The most reliable approach would be to combine many different signals. The verification method I propose here should only be used as a last measure if it would make the difference between the suspicion being below or above the threshold for taking action.

If the other signals can clearly put the pairs of account on one side of the threshold regardless of the equivalency of the passwords, then there is no need to put it in the suspect table in the first place.

4

There is a way to check that a password isn't a match to any password.

You could, at password change, verify that single password against every other password in the database since you'll have the unencrypted password. This could take a while, but it is feasible. This could easily lead to a DoS attack since a single action could cause high CPU for a prolonged time. Also, however you're keeping tabs on which users have matching passwords could be used to prioritize which passwords to crack. An attacker that already has all of the passwords and list of users with matching passwords could attempt to brute force the passwords with multiple accounts first.

As voiced by other answers, I don't think this should be a method used to determine duplicate accounts. Multiple accounts accessed from the same IP would probably provide fewer false positives. It'd be better to install a cookie indicating the user that was last logged in and quietly log when that cookie doesn't match the user currently logging in.

4
  • Why would a single action cause high CPU usage? Based on the OP, the system uses a very fast hashing mechanism (MD5) and no salt. So you just need to hash the user input and search the database once for the result.
    – Iszi
    Commented Nov 20, 2015 at 17:20
  • 2
    The OP is asking about using php's password_hash function which can use Bcrypt as the algorithm. Running password_verify on every password in the database every time someone changes their password can be quite taxing.
    – Erroneous
    Commented Nov 20, 2015 at 17:26
  • 2
    Ah, you're referring to after the upgrade - at which point I was (optimistically) assuming the OP would have realized the error of his ways and stopped doing user deduplication based on passwords.
    – Iszi
    Commented Nov 20, 2015 at 17:40
  • 1
    Yep. I agree that it is wrong to deduplicate based on passwords. If anything this shows that if you wanted to do it the wrong way then it is possible, but more trouble than it is worth.
    – Erroneous
    Commented Nov 20, 2015 at 22:07

You must log in to answer this question.