How should I ethically approach user password stor

2018-12-31 15:55发布

As I continue to build more and more websites and web applications I am often asked to store user's passwords in a way that they can be retrieved if/when the user has an issue (either to email a forgotten password link, walk them through over the phone, etc.) When I can I fight bitterly against this practice and I do a lot of ‘extra’ programming to make password resets and administrative assistance possible without storing their actual password.

When I can’t fight it (or can’t win) then I always encode the password in some way so that it, at least, isn’t stored as plaintext in the database—though I am aware that if my DB gets hacked it wouldn't take much for the culprit to crack the passwords, so that makes me uncomfortable.

In a perfect world folks would update passwords frequently and not duplicate them across many different sites—unfortunately I know MANY people that have the same work/home/email/bank password, and have even freely given it to me when they need assistance. I don’t want to be the one responsible for their financial demise if my DB security procedures fail for some reason.

Morally and ethically I feel responsible for protecting what can be, for some users, their livelihood even if they are treating it with much less respect. I am certain that there are many avenues to approach and arguments to be made for salting hashes and different encoding options, but is there a single ‘best practice’ when you have to store them? In almost all cases I am using PHP and MySQL if that makes any difference in the way I should handle the specifics.

Additional Information for Bounty

I want to clarify that I know this is not something you want to have to do and that in most cases refusal to do so is best. I am, however, not looking for a lecture on the merits of taking this approach I am looking for the best steps to take if you do take this approach.

In a note below I made the point that websites geared largely toward the elderly, mentally challenged, or very young can become confusing for people when they are asked to perform a secure password recovery routine. Though we may find it simple and mundane in those cases some users need the extra assistance of either having a service tech help them into the system or having it emailed/displayed directly to them.

In such systems the attrition rate from these demographics could hobble the application if users were not given this level of access assistance, so please answer with such a setup in mind.

Thanks to Everyone

This has been a fun question with lots of debate and I have enjoyed it. In the end I selected an answer that both retains password security (I will not have to keep plain text or recoverable passwords), but also makes it possible for the user base I specified to log into a system without the major drawbacks I have found from normal password recovery.

As always there were about 5 answers that I would like to have marked as correct for different reasons, but I had to choose the best one--all the rest got a +1. Thanks everyone!

Also, thanks to everyone in the Stack community who voted for this question and/or marked it as a favorite. I take hitting 100 up votes as a compliment and hope that this discussion has helped someone else with the same concern that I had.

26条回答
呛了眼睛熬了心
2楼-- · 2018-12-31 16:28

Make the answer to the user's security question a part of the encryption key, and don't store the security question answer as plain text (hash that instead)

查看更多
皆成旧梦
3楼-- · 2018-12-31 16:29

The only way to allow a user to retrieve their original password, is to encrypt it with the user's own public key. Only that user can then decrypt their password.

So the steps would be:

  1. User registers on your site (over SSL of course) without yet setting a password. Log them in automatically or provide a temporary password.
  2. You offer to store their public PGP key for future password retrieval.
  3. They upload their public PGP key.
  4. You ask them to set a new password.
  5. They submit their password.
  6. You hash the password using the best password hashing algorithm available (e.g. bcrypt). Use this when validating the next log-in.
  7. You encrypt the password with the public key, and store that separately.

Should the user then ask for their password, you respond with the encrypted (not hashed) password. If the user does not wish to be able to retrieve their password in future (they would only be able to reset it to a service-generated one), steps 3 and 7 can be skipped.

查看更多
时光乱了年华
4楼-- · 2018-12-31 16:30

I think the real question you should ask yourself is: 'How can I be better at convincing people?'

查看更多
低头抚发
5楼-- · 2018-12-31 16:32

I have the same issue. And at the same way I always think that someone hack my system it's not a matter of "if" but of "when".

So, when I must to do a website that need to store a recoverable confidential information, like a credit card or a password, what I do it's:

  • encrypt with: openssl_encrypt(string $data , string $method , string $password)
  • data arg:
    • the sensitive information (e.g. the user password)
    • serialize if necessary, e.g. if the information is a array of data like multiple sensitive information
  • password arg: use a information that only the user know like:
    • the user license plate
    • social security number
    • user phone number
    • the user mother name
    • a random string sended by email and/or by sms at register time
  • method arg:
    • choose one cipher method, like "aes-256-cbc"
  • NEVER store the information used in the "password" argument at database (or whatever place in the system)

When necessary to retrive this data just use the "openssl_decrypt()" function and ask the user for the answer. E.g.: "To receive your password answer the question: What's your cellphone number?"

PS 1: never use as a password a data stored in database. If you need to store the user cellphone number, then never use this information to encode the data. Always use a information that only the user know or that it's hard to someone non-relative know.

PS 2: for credit card information, like "one click buying", what I do is use the login password. This password is hashed in database (sha1, md5, etc), but at login time I store the plain-text password in session or in a non-persistent (i.e. at memory) secure cookie. This plain password never stay in database, indeed it's always stay in memory, destroyed at end of section. When the user click at "one click buying" button the system use this password. If the user was logged in with a service like facebook, twitter, etc, then I prompt the password again at buying time (ok, it's not a fully "on click") or then use some data of the service that user used to login (like the facebook id).

查看更多
琉璃瓶的回忆
6楼-- · 2018-12-31 16:33

Don't give up. The weapon you can use to convince your clients is non-repudiability. If you can reconstruct user passwords via any mechanism, you have given their clients a legal non-repudiation mechanism and they can repudiate any transaction that depends on that password, because there is no way the supplier can prove that they didn't reconstruct the password and put the transaction through themselves. If passwords are correctly stored as digests rather than ciphertext, this is impossible, ergo either the end-client executed the transaction himself or breached his duty of care w.r.t. the password. In either case that leaves the liability squarely with him. I've worked on cases where that would amount to hundreds of millions of dollars. Not something you want to get wrong.

查看更多
回忆,回不去的记忆
7楼-- · 2018-12-31 16:34

There's been a lot of discussion of security concerns for the user in response to this question, but I'd like to add a mentioning of benefits. So far, I've not seen one legitimate benefit mentioned for having a recoverable password stored on the system. Consider this:

  • Does the user benefit from having their password emailed to them? No. They receive more benefit from a one-time-use password reset link, which would hopefully allow them to choose a password they will remember.
  • Does the user benefit from having their password displayed on screen? No, for the same reason as above; they should choose a new password.
  • Does the user benefit from having a support person speak the password to the user? No; again, if the support person deems the user's request for their password as properly authenticated, it's more to the user's benefit to be given a new password and the opportunity to change it. Plus, phone support is more costly than automated password resets, so the company also doesn't benefit.

It seems the only ones that can benefit from recoverable passwords are those with malicious intent or supporters of poor APIs that require third-party password exchange (please don't use said APIs ever!). Perhaps you can win your argument by truthfully stating to your clients that the company gains no benefits and only liabilities by storing recoverable passwords.

Reading between the lines of these types of requests, you'll see that your clients probably don't understand or actually even care at all about how passwords are managed. What they really want is an authentication system that isn't so hard for their users. So in addition to telling them how they don't actually want recoverable passwords, you should offer them ways to make the authentication process less painful, especially if you don't need the heavy security levels of, say, a bank:

  • Allow the user to use their email address for their user name. I've seen countless cases where the user forgets their user name, but few forget their email address.
  • Offer OpenID and let a third-party pay for the costs of user forgetfulness.
  • Ease off on the password restrictions. I'm sure we've all been incredibly annoyed when some web site doesn't allow your preferred password because of useless requirements like "you can't use special characters" or "your password is too long" or "your password must start with a letter." Also, if ease of use is a larger concern than password strength, you could loosen even the non-stupid requirements by allowing shorter passwords or not requiring a mix of character classes. With loosened restrictions, users will be more likely to use a password they won't forget.
  • Don't expire passwords.
  • Allow the user to reuse an old password.
  • Allow the user to choose their own password reset question.

But if you, for some reason (and please tell us the reason) really, really, really need to be able to have a recoverable password, you could shield the user from potentially compromising their other online accounts by giving them a non-password-based authentication system. Because people are already familiar with username/password systems and they are a well-exercised solution, this would be a last resort, but there's surely plenty of creative alternatives to passwords:

  • Let the user choose a numeric pin, preferably not 4-digit, and preferably only if brute-force attempts are protected against.
  • Have the user choose a question with a short answer that only they know the answer to, will never change, they will always remember, and they don't mind other people finding out.
  • Have the user enter a user name and then draw an easy-to-remember shape with sufficient permutations to protect against guessing (see this nifty photo of how the G1 does this for unlocking the phone).
  • For a children's web site, you could auto-generate a fuzzy creature based on the user name (sort of like an identicon) and ask the user to give the creature a secret name. They can then be prompted to enter the creature's secret name to log in.
查看更多
登录 后发表回答