Storing plaintext passwords for detecting fraud

passwords

I am well aware of best practices for storing user passwords:

  • Never store passwords in plaintext
  • Never store encrypted passwords; always store password hashes
  • Always salt your password hash to deter brute force attacks
  • Always use unique salts to deter attacks using rainbow tables.

However, I have recently came upon on a potentially legitimate use case for keeping plaintext (or plaintext-accessible encrypted) user passwords: fraud detection. For example, if we have a system that needs to restrict purchases to 1 (or a small number) per person, we have observed that fraudsters often use the same password over and over, so if we have detected fraudulent purchases on one account, we can use the fact that password matches as a useful signal in a fraud detection system.

But implementing such a system requires breaking all the best practices for password storage.

Question: If it is determined that the fraud-detection ability of being to retrieve passwords is necessary, what are the best practices for storing passwords securely but in a way that is plaintext-accessible?

Best Answer

In this case you could, upon registration, generate a hash of the entered password for every salt used so far, then check these salted and hashed passwords against all the passwords already stored.

You could even cache all the salts used so far, this is potentially a smaller list than having to loop through all passwords every time to collect these.

If that is too expensive to compute on each registration, limit the number of salts you generate (pick randomly from a limited list) to reduce calculation time. That'll still be safer (by far) than storing plain text passwords.

Note that if this is just for the sake of fraud detection, a security breach and resulting (huge) negative publicity is going to cost you much more, wiping out any advantages you gained from catching a few fraudsters this way.