How should I ethically approach user password storage for later plaintext retrieval? - security

Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
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.

How about taking another approach or angle at this problem? Ask why the password is required to be in plaintext: if it's so that the user can retrieve the password, then strictly speaking you don't really need to retrieve the password they set (they don't remember what it is anyway), you need to be able to give them a password they can use.
Think about it: if the user needs to retrieve the password, it's because they've forgotten it. In which case a new password is just as good as the old one. But, one of the drawbacks of common password reset mechanisms used today is that the generated passwords produced in a reset operation are generally a bunch of random characters, so they're difficult for the user to simply type in correctly unless they copy-n-paste. That can be a problem for less savvy computer users.
One way around that problem is to provide auto-generated passwords that are more or less natural language text. While natural language strings might not have the entropy that a string of random characters of the same length has, there's nothing that says your auto-generated password needs to have only 8 (or 10 or 12) characters. Get a high-entropy auto-generated passphrase by stringing together several random words (leave a space between them, so they're still recognizable and typeable by anyone who can read). Six random words of varying length are probably easier to type correctly and with confidence than 10 random characters, and they can have a higher entropy as well. For example, the entropy of a 10 character password drawn randomly from uppercase, lowercase, digits and 10 punctuation symbols (for a total of 72 valid symbols) would have an entropy of 61.7 bits. Using a dictionary of 7776 words (as Diceware uses) which could be randomly selected for a six word passphrase, the passphrase would have an entropy of 77.4 bits. See the Diceware FAQ for more info.
a passphrase with about 77 bits of entropy: "admit prose flare table acute flair"
a password with about 74 bits of entropy: "K:&$R^tt~qkD"
I know I'd prefer typing the phrase, and with copy-n-paste, the phrase is no less easy to use that the password either, so no loss there. Of course if your website (or whatever the protected asset is) doesn't need 77 bits of entropy for an auto-generated passphrase, generate fewer words (which I'm sure your users would appreciate).
I understand the arguments that there are password protected assets that really don't have a high level of value, so the breach of a password might not be the end of the world. For example, I probably wouldn't care if 80% of the passwords I use on various websites was breached: all that could happen is a someone spamming or posting under my name for a while. That wouldn't be great, but it's not like they'd be breaking into my bank account. However, given the fact that many people use the same password for their web forum sites as they do for their bank accounts (and probably national security databases), I think it would be best to handle even those 'low-value' passwords as non-recoverable.

Imagine someone has commissioned a large building to be built - a bar, let's say - and the following conversation takes place:
Architect: For a building of this size and capacity, you will need fire exits here, here, and here.
Client: No, that's too complicated and expensive to maintain, I don't want any side doors or back doors.
Architect: Sir, fire exits are not optional, they are required as per the city's fire code.
Client: I'm not paying you to argue. Just do what I asked.
Does the architect then ask how to ethically build this building without fire exits?
In the building and engineering industry, the conversation is most likely to end like this:
Architect: This building cannot be built without fire exits. You can go to any other licensed professional and he will tell you the same thing. I'm leaving now; call me back when you are ready to cooperate.
Computer programming may not be a licensed profession, but people often seem to wonder why our profession doesn't get the same respect as a civil or mechanical engineer - well, look no further. Those professions, when handed garbage (or outright dangerous) requirements, will simply refuse. They know it is not an excuse to say, "well, I did my best, but he insisted, and I've gotta do what he says." They could lose their license for that excuse.
I don't know whether or not you or your clients are part of any publicly-traded company, but storing passwords in any recoverable form would cause you to to fail several different types of security audits. The issue is not how difficult it would be for some "hacker" who got access to your database to recover the passwords. The vast majority of security threats are internal. What you need to protect against is some disgruntled employee walking off with all the passwords and selling them to the highest bidder. Using asymmetrical encryption and storing the private key in a separate database does absolutely nothing to prevent this scenario; there's always going to be someone with access to the private database, and that's a serious security risk.
There is no ethical or responsible way to store passwords in a recoverable form. Period.

You could encrypt the password + a salt with a public key. For logins just check if the stored value equals the value calculated from the user input + salt. If there comes a time, when the password needs to be restored in plaintext, you can decrypt manually or semi-automatically with the private key. The private key may be stored elsewhere and may additionally be encrypted symmetrically (which will need a human interaction to decrypt the password then).
I think this is actually kind of similar to the way the Windows Recovery Agent works.
Passwords are stored encrypted
People can login without decrypting to plaintext
Passwords can be recovered to plaintext, but only with a private key, that can be stored outside the system (in a bank safe, if you want to).

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.

You can not ethically store passwords for later plaintext retrieval. It's as simple as that. Even Jon Skeet can not ethically store passwords for later plaintext retrieval. If your users can retrieve passwords in plain text somehow or other, then potentially so too can a hacker who finds a security vulnerability in your code. And that's not just one user's password being compromised, but all of them.
If your clients have a problem with that, tell them that storing passwords recoverably is against the law. Here in the UK at any rate, the Data Protection Act 1998 (in particular, Schedule 1, Part II, Paragraph 9) requires data controllers to use the appropriate technical measures to keep personal data secure, taking into account, among other things, the harm that might be caused if the data were compromised -- which might be considerable for users who share passwords among sites. If they still have trouble grokking the fact that it's a problem, point them to some real-world examples, such as this one.
The simplest way to allow users to recover a login is to e-mail them a one-time link that logs them in automatically and takes them straight to a page where they can choose a new password. Create a prototype and show it in action to them.
Here are a couple of blog posts I wrote on the subject:
http://jamesmckay.net/2009/09/if-you-are-saving-passwords-in-clear-text-you-are-probably-breaking-the-law/
http://jamesmckay.net/2008/06/easy-login-recovery-without-compromising-security/
Update: we are now starting to see lawsuits and prosecutions against companies that fail to secure their users' passwords properly. Example: LinkedIn slapped with $5 million class action lawsuit; Sony fined £250,000 over PlayStation data hack. If I recall correctly, LinkedIn was actually encrypting its users' passwords, but the encryption it was using was too weak to be effective.

After reading this part:
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.
I'm left wondering if any of these requirements mandate a retrievable password system. For instance:
Aunt Mabel calls up and says "Your internet program isn't working, I don't know my password". "OK" says the customer service drone "let me check a few details and then I'll give you a new password. When you next log in it will ask you if you want to keep that password or change it to something you can remember more easily."
Then the system is set up to know when a password reset has happened and display a "would you like to keep the new password or choose a new one" message.
How is this worse for the less PC-literate than being told their old password? And while the customer service person can get up to mischief, the database itself is much more secure in case it is breached.
Comment what's bad on my suggestion and I'll suggest a solution that actually does what you initially wanted.

Michael Brooks has been rather vocal about CWE-257 - the fact that whatever method you use, you (the administrator) can still recover the password. So how about these options:
Encrypt the password with someone else's public key - some external authority. That way you can't reconstruct it personally, and the user will have to go to that external authority and ask to have their password recovered.
Encrypt the password using a key generated from a second passphrase. Do this encryption client-side and never transmit it in the clear to the server. Then, to recover, do the decryption client-side again by re-generating the key from their input. Admittedly, this approach is basically using a second password, but you can always tell them to write it down, or use the old security-question approach.
I think 1. is the better choice, because it enables you to designate someone within the client's company to hold the private key. Make sure they generate the key themselves, and store it with instructions in a safe etc. You could even add security by electing to only encrypt and supply certain characters from the password to the internal third party so they would have to crack the password to guess it. Supplying these characters to the user, they will probably remember what it was!

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.

Pursuant to the comment I made on the question:
One important point has been very glossed over by nearly everyone... My initial reaction was very similar to #Michael Brooks, till I realized, like #stefanw, that the issue here is broken requirements, but these are what they are.
But then, it occured to me that that might not even be the case! The missing point here, is the unspoken value of the application's assets. Simply speaking, for a low value system, a fully secure authentication mechanism, with all the process involved, would be overkill, and the wrong security choice.
Obviously, for a bank, the "best practices" are a must, and there is no way to ethically violate CWE-257. But it's easy to think of low value systems where it's just not worth it (but a simple password is still required).
It's important to remember, true security expertise is in finding appropriate tradeoffs, NOT in dogmatically spouting the "Best Practices" that anyone can read online.
As such, I suggest another solution:
Depending on the value of the system, and ONLY IF the system is appropriately low-value with no "expensive" asset (the identity itself, included), AND there are valid business requirements that make proper process impossible (or sufficiently difficult/expensive), AND the client is made aware of all the caveats...
Then it could be appropriate to simply allow reversible encryption, with no special hoops to jump through.
I am stopping just short of saying not to bother with encryption at all, because it is very simple/cheap to implement (even considering passible key management), and it DOES provide SOME protection (more than the cost of implementing it). Also, its worth looking at how to provide the user with the original password, whether via email, displaying on the screen, etc.
Since the assumption here is that the value of the stolen password (even in aggregate) is quite low, any of these solutions can be valid.
Since there is a lively discussion going on, actually SEVERAL lively discussions, in the different posts and seperate comment threads, I will add some clarifications, and respond to some of the very good points that have been raised elsewhere here.
To start, I think it's clear to everyone here that allowing the user's original password to be retrieved, is Bad Practice, and generally Not A Good Idea. That is not at all under dispute...
Further, I will emphasize that in many, nay MOST, situations - it's really wrong, even foul, nasty, AND ugly.
However, the crux of the question is around the principle, IS there any situation where it might not be necessary to forbid this, and if so, how to do so in the most correct manner appropriate to the situation.
Now, as #Thomas, #sfussenegger and few others mentioned, the only proper way to answer that question, is to do a thorough risk analysis of any given (or hypothetical) situation, to understand what's at stake, how much it's worth to protect, and what other mitigations are in play to afford that protection.
No, it is NOT a buzzword, this is one of the basic, most important tools for a real-live security professional. Best practices are good up to a point (usually as guidelines for the inexperienced and the hacks), after that point thoughtful risk analysis takes over.
Y'know, it's funny - I always considered myself one of the security fanatics, and somehow I'm on the opposite side of those so-called "Security Experts"... Well, truth is - because I'm a fanatic, and an actual real-life security expert - I do not believe in spouting "Best Practice" dogma (or CWEs) WITHOUT that all-important risk analysis.
"Beware the security zealot who is quick to apply everything in their tool belt without knowing what the actual issue is they are defending against. More security doesn’t necessarily equate to good security."
Risk analysis, and true security fanatics, would point to a smarter, value/risk -based tradeoff, based on risk, potential loss, possible threats, complementary mitigations, etc. Any "Security Expert" that cannot point to sound risk analysis as the basis for their recommendations, or support logical tradeoffs, but would instead prefer to spout dogma and CWEs without even understanding how to perform a risk analysis, are naught but Security Hacks, and their Expertise is not worth the toilet paper they printed it on.
Indeed, that is how we get the ridiculousness that is Airport Security.
But before we talk about the appropriate tradeoffs to make in THIS SITUATION, let's take a look at the apparent risks (apparent, because we don't have all the background information on this situation, we are all hypothesizing - since the question is what hypothetical situation might there be...)
Let's assume a LOW-VALUE system, yet not so trival that it's public access - the system owner wants to prevent casual impersonation, yet "high" security is not as paramount as ease of use. (Yes, it is a legitimate tradeoff to ACCEPT the risk that any proficient script-kiddie can hack the site... Wait, isn't APT in vogue now...?)
Just for example, let's say I'm arranging a simple site for a large family gathering, allowing everyone to brainstorm on where we want to go on our camping trip this year. I'm less worried about some anonymous hacker, or even Cousin Fred squeezing in repeated suggestions to go back to Lake Wantanamanabikiliki, as I am about Aunt Erma not being able to logon when she needs to. Now, Aunt Erma, being a nuclear physicist, isn't very good at remembering passwords, or even with using computers at all... So I want to remove all friction possible for her. Again, I'm NOT worried about hacks, I just dont want silly mistakes of wrong login - I want to know who is coming, and what they want.
Anyway.
So what are our main risks here, if we symmetrically encrypt passwords, instead of using a one-way hash?
Impersonating users? No, I've already accepted that risk, not interesting.
Evil administrator? Well, maybe... But again, I dont care if someone can impersonate another user, INTERNAL or no... and anyway a malicious admin is gonna get your password no matter what - if your admin's gone bad, its game over anyway.
Another issue that's been raised, is the identity is actually shared between several systems. Ah! This is a very interesting risk, that requires a closer look.
Let me start by asserting that it's not the actual identity thats shared, rather the proof, or the authentication credential. Okay, since a shared password will effectively allow me entrance to another system (say, my bank account, or gmail), this is effectively the same identity, so it's just semantics... Except that it's not. Identity is managed seperately by each system, in this scenario (though there might be third party id systems, such as OAuth - still, its seperate from the identity in this system - more on this later).
As such, the core point of risk here, is that the user will willingly input his (same) password into several different systems - and now, I (the admin) or any other hacker of my site will have access to Aunt Erma's passwords for the nuclear missile site.
Hmmm.
Does anything here seem off to you?
It should.
Let's start with the fact that protecting the nuclear missiles system is not my responsibility, I'm just building a frakkin family outing site (for MY family). So whose responsibility IS it? Umm... How about the nuclear missiles system? Duh.
Second, If I wanted to steal someone's password (someone who is known to repeatedly use the same password between secure sites, and not-so-secure ones) - why would I bother hacking your site? Or struggling with your symmetric encryption? Goshdarnitall, I can just put up my own simple website, have users sign up to receive VERY IMPORTANT NEWS about whatever they want... Puffo Presto, I "stole" their passwords.
Yes, user education always does come back to bite us in the hienie, doesn't it?
And there's nothing you can do about that... Even if you WERE to hash their passwords on your site, and do everything else the TSA can think of, you added protection to their password NOT ONE WHIT, if they're going to keep promiscuously sticking their passwords into every site they bump into. Don't EVEN bother trying.
Put another way, You don't own their passwords, so stop trying to act like you do.
So, my Dear Security Experts, as an old lady used to ask for Wendy's, "WHERE's the risk?"
Another few points, in answer to some issues raised above:
CWE is not a law, or regulation, or even a standard. It is a collection of common weaknesses, i.e. the inverse of "Best Practices".
The issue of shared identity is an actual problem, but misunderstood (or misrepresented) by the naysayers here. It is an issue of sharing the identity in and of itself(!), NOT about cracking the passwords on low-value systems. If you're sharing a password between a low-value and a high-value system, the problem is already there!
By the by, the previous point would actually point AGAINST using OAuth and the like for both these low-value systems, and the high-value banking systems.
I know it was just an example, but (sadly) the FBI systems are not really the most secured around. Not quite like your cat's blog's servers, but nor do they surpass some of the more secure banks.
Split knowledge, or dual control, of encryption keys do NOT happen just in the military, in fact PCI-DSS now requires this from basically all merchants, so its not really so far out there anymore (IF the value justifies it).
To all those who are complaining that questions like these are what makes the developer profession look so bad: it is answers like those, that make the security profession look even worse. Again, business-focused risk analysis is what is required, otherwise you make yourself useless. In addition to being wrong.
I guess this is why it's not a good idea to just take a regular developer and drop more security responsibilities on him, without training to think differently, and to look for the correct tradeoffs. No offense, to those of you here, I'm all for it - but more training is in order.
Whew. What a long post...
But to answer your original question, #Shane:
Explain to the customer the proper way to do things.
If he still insists, explain some more, insist, argue. Throw a tantrum, if needed.
Explain the BUSINESS RISK to him. Details are good, figures are better, a live demo is usually best.
IF HE STILL insists, AND presents valid business reasons - it's time for you to do a judgement call:
Is this site low-to-no-value? Is it really a valid business case? Is it good enough for you? Are there no other risks you can consider, that would outweigh valid business reasons? (And of course, is the client NOT a malicious site, but thats duh).
If so, just go right ahead. It's not worth the effort, friction, and lost usage (in this hypothetical situation) to put the necessary process in place. Any other decision (again, in this situation) is a bad tradeoff.
So, bottom line, and an actual answer - encrypt it with a simple symmetrical algorithm, protect the encryption key with strong ACLs and preferably DPAPI or the like, document it and have the client (someone senior enough to make that decision) sign off on it.

How about a halfway house?
Store the passwords with a strong encryption, and don't enable resets.
Instead of resetting passwords, allow sending a one-time password (that has to be changed as soon as the first logon occurs). Let the user then change to whatever password they want (the previous one, if they choose).
You can "sell" this as a secure mechanism for resetting passwords.

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:
User registers on your site (over SSL of course) without yet setting a password. Log them in automatically or provide a temporary password.
You offer to store their public PGP key for future password retrieval.
They upload their public PGP key.
You ask them to set a new password.
They submit their password.
You hash the password using the best password hashing algorithm available (e.g. bcrypt). Use this when validating the next log-in.
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.

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

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)
PHP manual.
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).

Securing credentials is not a binary operation: secure/not secure. Security is all about risk assessment and is measured on a continuum. Security fanatics hate to think this way, but the ugly truth is that nothing is perfectly secure. Hashed passwords with stringent password requirements, DNA samples, and retina scans are more secure but at a cost of development and user experience. Plaintext passwords are far less secure but are cheaper to implement (but should be avoided). At end of the day, it comes down to a cost/benefit analysis of a breach. You implement security based on the value of the data being secured and its time-value.
What is the cost of someone's password getting out into the wild? What is the cost of impersonation in the given system? To the FBI computers, the cost could be enormous. To Bob's one-off five-page website, the cost could be negligible. A professional provides options to their customers and, when it comes to security, lays out the advantages and risks of any implementation. This is doubly so if the client requests something that could put them at risk because of failing to heed industry standards. If a client specifically requests two-way encryption, I would ensure you document your objections but that should not stop you from implementing in the best way you know. At the end of the day, it is the client's money. Yes, you should push for using one-way hashes but to say that is absolutely the only choice and anything else is unethical is utter nonsense.
If you are storing passwords with two-way encryption, security all comes down to key management. Windows provides mechanisms to restrict access to certificates private keys to administrative accounts and with passwords. If you are hosting on other platform's, you would need to see what options you have available on those. As others have suggested, you can use asymmetric encryption.
There is no law (neither the Data Protection Act in the UK) of which I'm aware that states specifically that passwords must be stored using one-way hashes. The only requirement in any of these laws is simply that reasonable steps are taken for security. If access to the database is restricted, even plaintext passwords can qualify legally under such a restriction.
However, this does bring to light one more aspect: legal precedence. If legal precedence suggests that you must use one-way hashes given the industry in which your system is being built, then that is entirely different. That is the ammunition you use to convince your customer. Barring that, the best suggestion to provide a reasonable risk assessment, document your objections and implement the system in the most secure way you can given customer's requirements.

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)

I implement multiple-factor authentication systems for a living, so for me it is natural to think that you can either reset or reconstruct the password, while temporarily using one less factor to authenticate the user for just the reset/recreation workflow. Particularly the use of OTPs (one-time passwords) as some of the additional factors, mitigates much of the risk if the time window is short for the suggested workflow. We've implemented software OTP generators for smartphones (that most users already carry with themselves all day) with great success. Before complains of a commercial plug appear, what I'm saying is that we can lower the risks inherent of keeping passwords easily retrievable or resettable when they aren't the only factor used to authenticate an user. I concede that for the password reuse among sites scenarios the situation is still not pretty, as the user will insist to have the original password because he/she wants to open up the other sites too, but you can try to deliver the reconstructed password in the safest possible way (htpps and discreet appearance on the html).

Sorry, but as long as you have some way to decode their password, there's no way it's going to be secure. Fight it bitterly, and if you lose, CYA.

Just came across this interesting and heated discussion.
What surprised me most though was, how little attention was payed to the following basic question:
Q1. What are the actual reasons the user insists on having access to plain text stored password? Why is it of so much value?
The information that users are elder or young does not really answer that question. But how a business decision can be made without proper understanding customer's concern?
Now why it matters?
Because if the real cause of customers' request is the system that is painfully hard to use, then maybe addressing the exact cause would solve the actual problem?
As I don't have this information and cannot speak to those customers, I can only guess: It is about usability, see above.
Another question I have seen asked:
Q2. If user does not remember the password in first place, why does the old password matter?
And here is possible answer.
If you have cat called "miaumiau" and used her name as password but forgot you did, would you prefer to be reminded what it was or rather being sent something like "#zy*RW(ew"?
Another possible reason is that the user considers it a hard work to come up with a new password! So having the old password sent back gives the illusion of saving her from that painful work again.
I am just trying to understand the reason. But whatever the reason is, it is the reason not the cause that has to be addressed.
As user, I want things simple! I don't want to work hard!
If I log in to a news site to read newspapers, I want to type 1111 as password and be through!!!
I know it is insecure but what do I care about someone getting access to my "account"? Yes, he can read the news too!
Does the site store my "private" information?
The news I read today?
Then it is the site's problem, not mine!
Does the site show private information to authenticated user?
Then don't show it in first place!
This is just to demonstrate user's attitude to the problem.
So to summarize, I don't feel it is a problem of how to "securely" store plain text passwords (which we know is impossible) but rather how to address customers actual concern.

Handling lost/forgotten passwords:
Nobody should ever be able to recover passwords.
If users forgot their passwords, they must at least know their user names or email addresses.
Upon request, generate a GUID in the Users table and sent an email containing a link containing the guid as a parameter to the user's email address.
The page behind the link verifies that the parameter guid really exists (probably with some timeout logic), and asks the user for a new password.
If you need to have hotline help users, add some roles to your grants model and allow the hotline role to temporarily login as identified user. Log all such hotline logins. For example, Bugzilla offers such an impersonation feature to admins.

What about emailing the plaintext password upon registration, before getting it encrypted and lost? I've seen a lot of websites do it, and getting that password from the user's email is more secure than leaving it around on your server/comp.

If you can't just reject the requirement to store recoverable passwords, how about this as your counter-argument.
We can either properly hash passwords and build a reset mechanism for the users, or we can remove all personally identifiable information from the system. You can use an email address to set up user preferences, but that's about it. Use a cookie to automatically pull preferences on future visits and throw the data away after a reasonable period.
The one option that is often overlooked with password policy is whether a password is really even needed. If the only thing your password policy does is cause customer service calls, maybe you can get rid of it.

Do the users really need to recover (e.g. be told) what the password they forgot was, or do they simply need to be able to get onto the system? If what they really want is a password to logon, why not have a routine that simply changes the old password (whatever it is) to a new password that the support person can give to the person that lost his password?
I have worked with systems that do exactly this. The support person has no way of knowing what the current password is, but can reset it to a new value. Of course all such resets should be logged somewhere and good practice would be to generate an email to the user telling him that the password has been reset.
Another possibility is to have two simultaneous passwords permitting access to an account. One is the "normal" password that the user manages and the other is like a skeleton/master key that is known by the support staff only and is the same for all users. That way when a user has a problem the support person can login to the account with the master key and help the user change his password to whatever. Needless to say, all logins with the master key should be logged by the system as well. As an extra measure, whenever the master key is used you could validate the support persons credentials as well.
-EDIT- In response to the comments about not having a master key: I agree that it is bad just as I believe it is bad to allow anyone other than the user to have access to the user's account. If you look at the question, the whole premise is that the customer mandated a highly compromised security environment.
A master key need not be as bad as would first seem. I used to work at a defense plant where they perceived the need for the mainframe computer operator to have "special access" on certain occasions. They simply put the special password in a sealed envelope and taped it to the operator's desk. To use the password (which the operator did not know) he had to open the envelope. At each change of shift one of the jobs of the shift supervisor was to see if the envelope had been opened and if so immediately have the password changed (by another department) and the new password was put in a new envelope and the process started all over again. The operator would be questioned as to why he had opened it and the incident would be documented for the record.
While this is not a procedure that I would design, it did work and provided for excellent accountability. Everything was logged and reviewed, plus all the operators had DOD secret clearances and we never had any abuses.
Because of the review and oversight, all the operators knew that if they misused the privilege of opening the envelope they were subject to immediate dismissal and possible criminal prosecution.
So I guess the real answer is if one wants to do things right one hires people they can trust, do background checks and exercise proper management oversight and accountability.
But then again if this poor fellow's client had good management they wouldn't have asked for such a security comprimised solution in the first place, now would they?

From the little that I understand about this subject, I believe that if you are building a website with a signon/password, then you should not even see the plaintext password on your server at all. The password should be hashed, and probably salted, before it even leaves the client.
If you never see the plaintext password, then the question of retrieval doesn't arise.
Also, I gather (from the web) that (allegedly) some algorithms such as MD5 are no longer considered secure. I have no way of judging that myself, but it is something to consider.

open a DB on a standalone server and give an encrypted remote connection to each web server that requires this feature.
it does not have to be a relational DB, it can be a file system with FTP access, using folders and files instead of tables and rows.
give the web servers write-only permissions if you can.
Store the non-retrievable encryption of the password in the site's DB (let's call it "pass-a") like normal people do :)
on each new user (or password change) store a plain copy of the password in the remote DB. use the server's id, the user's ID and "pass-a" as a composite key for this password. you can even use a bi-directional encryption on the password to sleep better at night.
now in order for someone to get both the password and it's context (site id + user id + "pass-a"), he has to:
hack the website's DB to get a ("pass-a", user id ) pair or pairs.
get the website's id from some config file
find and hack into the remote passwords DB.
you can control the accessibility of the password retrieval service (expose it only as a secured web service, allow only certain amount of passwords retrievals per day, do it manually, etc.), and even charge extra for this "special security arrangement".
The passwords retrieval DB server is pretty hidden as it does not serve many functions and can be better secured (you can tailor permissions, processes and services tightly).
all in all, you make the work harder for the hacker. the chance of a security breach on any single server is still the same, but meaningful data (a match of account and password) will be hard to assemble.

Another option you may not have considered is allowing actions via email. It is a bit cumbersome, but I implemented this for a client that needed users "outside" their system to view (read only) certain parts of the system. For example:
Once a user is registered, they have full access (like a regular
website). Registration must include an email.
If data or an action is needed and the user doesn't
remember their password, they can still perform the action by
clicking on a special "email me for permission" button, right next to the regular "submit" button.
The request is then sent out to the email with a hyperlink asking if they want the action to be performed. This is similar to a password reset email link, but instead of resetting the password it performs the one-time action.
The user then clicks "Yes", and it confirms that the data should be shown, or the action should be performed, data revealed, etc.
As you mentioned in the comments, this won't work if the email is compromised, but it does address #joachim 's comment about not wanting to reset the password. Eventually, they would have to use the password reset, but they could do that at a more convenient time, or with assistance of an administrator or friend, as needed.
A twist to this solution would be to send the action request to a third party trusted administrator. This would work best in cases with the elderly, mentally challenged, very young or otherwise confused users. Of course this requires a trusted administrator for these people to support their actions.

Salt-and-hash the user's password as normal. When logging the user in, allow both the user's password (after salting/hashing), but also allow what the user literally entered to match too.
This allows the user to enter their secret password, but also allows them to enter the salted/hashed version of their password, which is what someone would read from the database.
Basically, make the salted/hashed password be also a "plain-text" password.

Related

Secure way to do password retrieval/resetting?

Before I begin, my reason for not using OAuth is I believe it is not really something we should be using on this project, we're targeting a platform that will be packaged and resold to companies, which connect to their own set of uses that we really don't want to have accounts that we are not %100 in control of, we don't want it to be a shared-login with other services, and we don't want to force people into getting a google/yahoo/openID/aol/facebook/blogger/wordpress/whatever account.
Now then, What I would like is the best way to let users re-set a password.
I hate the concept of secret-questions: What school did you goto? Well, lets check your facebook page. What was your first-grade teacher? Lets just ask them casually.
I hate using one-time-passwords via email: Since when is email secure? Your boss reads it. Your sending out spam emails to me every day. It went into your junk-bin. It's not sent encrypted.
I don't want to use a password to reset a password either. This just doesn't make sense.
I'm really out of ideas here for the best way to do this, so I figure I would ask the community.
Your problem is that you need to outsource trust. If the user forgets their password, you no longer have a direct way to trust them, so you have to use an outside source to reestablish your relationship.
If you think email is insecure (which it is, actually), you could try telephone. Give them a call with the temporary password. Or a fax. Or snail mail, or an SMS, etc.
This is as secure as the phone lines/postal carriers over which the reset travels, and in most areas, telephone intercepts or tampering with the mail is strictly punished by the law.
If that's no good, consider issuing users an OTP token, or smartcard, or something.
Barring being able to vet the person in person, I think you've listed all the reasonable options I've seen. In my opinion the one-time-password via email is the superior option as people tend to at least want to keep their email private. I personally hate secret questions - too big of a chance of the answers being public (see Sarah Palin email incident). If you are going to do secret questions, at least let the user choose their own questions.
I think this requires a difficult implementation but sending new password to user's mobile phone as a text message may be an alternative solution. Mobile phones are much more secure than personal inbox.
Then, users are asked to enter their mobile phone numbers. Users that doesn't want that functionality are provided new passwords by email.
Make users select a secret image (or images). Or make user upload their own image.
This works better than secret questions. Secret questions have two common problems:
user gives an answer that can be easily obtained by others.
user knows about first problem and instead of a real answer gives a random answer, later on forgetting themselves what it was.
By making user to select secret image(s) or better yet upload their own images. It'll be easier for user to recall it later when recovering the password, since it's easier to make visual associations.
When recovering the password present user with several choices to pick the right image.
So you actually want the user to prove that he is who he claims he is, without revealing information about himself (assuming you can get ANY information with social hacking)
There are 3 ways for authentication: Something you are (biometrics), Something you have (dongle for example) and Something you know (password,response...). 2 or 3-way authentication is much more secure than 1-way.
Password reset/recovery, by definition reduces the security of the authentication procedure, because its now not A, but (A or B). (A= password, B=recover-password)
Therefore, even if your authentication procedure is 1-way (password), your recovery processes should be a 2-way authentication.
Let's see what are your options for the password recovery process:
Something you are (SysAdmin that recognize you - usually not good for 5000 workers organization, Voice-print - too expensive to implement, ...)
Something you have (e-mail account, phone number, ...)
Something you know (personal details)
Notice that corporate-ID tag with picture is a 2-way authentication (both something you are and something you have).
I think the best procedure is for the employee to physically go to the IT department, show his picture ID, and ask for a password reset.
If this is infeasible (too far - a remote branch for example), try to use a deligator who is recognized and can be trusted over the phone, so the employee will have to show the ID-tag to a local deligator.
If you can't use the 'Something you are' - you're left with something you have (e-mail, phone-number,your own PC) and something you know (personal details...). You can't escape it.

Is there a security reason not to reveal the existence of a user ID?

I've noticed that on some sites, when you request a password reminder or sign in, they'll tell you if the user doesn't exist (I think Meetup does this). Other sites will simply say "the user/password combination is invalid" (Google, I believe, does this).
Is there a security reason for not revealing the existence of a user id?
Yes there is.
You want to give attackers as little information as possible
If an attacker knows a username, they can attempt to attack that users email account. for example, if I know your login is chris#gmail.com I can attempt to break into your gmail account. They can also see what other sites you might registered at, and attempt to break into those sites (perhaps a site author didn't properly secure their db), and steal a password and attempt to use this password against other sites that chris#gmail.com is registered at.
If the attacker doesn't know what a valid username is, they essentially have to crack a password that is essentialy: Username.Length + Password.Length long, which increases the time it takes to crack an account.
Yes: don't give any password generating bots a reason to try to crack that account.
Edit:
Also I imagine, you can't contact them and claim that your email account was hacked on that user account and give a new (fake) address.
Besides the other reasons given, apart from hacking attempts, there can be a privacy concern. Sometimes the userid can be related to the person: when the user has a standard nick that uses in many sites, or when he uses a full -and uncommon- name; or, more critically, when the userid corresponds to a document number -as some e-banking sites do. Giving freely that info (efectively telling everybody "this userid is in my database") could be an serious privacy issue.
No, there isn't a good security reason for it. There are security reasons for it - just not good ones.
The same answer has been given here and elsewhere over and over: it gives the attacker extra information and you want to give them as little as possible. This only works against stupid attackers and they are not the ones you have to worry about. There is a major flaw with this argument - both from a theoretical and a practical perspective.
The username can often be checked in other ways anyway (practical)
The example of email is particularly ironic, since the entire point of an email address is to give it to other people, so that they can email you. Email addresses are not secret. (Of course, you would not want to give a list of addresses that exist, but saying whether the given address exists or not is a different matter.)
In cases other than email you can often check for a username by attempting to register with it. If the username already exists the system has no choice but to tell you so! Even if it tried to be coy about it and gave you a generic error an attacker with half a brain would still figure it out, while normal users would be annoyed at not being able to register and leave.
The username is not a secret (theoretical)
In security it is important to define what is a secret and what isn't. If people believe the username is secret and it isn't that's a problem - they have the illusion of security, which is worse than no security. The user needs to be clear on this: the password is secret, the username is not. Even if you are not aware of any ways to obtain the username you cannot rely on the fact that maybe someone who has your password won't have your username. If your password is compromised it's all over.
Since the username typically cannot be truly secret (it identifies the user, after all) it can become a "half-secret": something that's not usually revealed, but is if you push hard enough. People will often think that two "half-secrets" make a secret - but they don't. Of course, they don't think of it in those terms. Instead they will think "it's not so bad if I have an easy PIN, because nobody can use it without my bank card anyway" and separately think "it's not so bad if I lose my bank card, because nobody can use it without the PIN anyway".
Even if the username was a secret it would not improve security. Why not? Because you now simply have two passwords. Two passwords is not "defence in depth" - it is simply one password that has been split into two parts (one of which is quite easy to compromise). It's less effective than just making the password twice as long (or twice as complex).
it gives an attacker one more thing it needs to find. it's an easy requirement, but it is something anyone with a good reason should know, but isn't necessarily known by someone who shouldn't be there.
As a general rule of thumb, don't give an attacker any more information that is absolutely necessary. Is someone enters an email address that's not in your system, you don't have to tell them whether that email exists or not, so don't.
There are certainly stronger forms of defence, but for "defence in depth" every little thing adds up.

Are there any published frameworks or standards for passwords and website membership?

I am currently working on a project in which we are creating a large public website for my organization. This site is going to allow out clients to register and log in to obtain sensitive personal information.
From experience I know some of the basics like requiring a complex password and requiring an email address for a password reset that are common used.
Basically what I'm looking for is some sort of well documented recommendation or standards(like NIST or ISO) for these kinds of requirements.
I need to present this to a higher level director who is insisting on us:
not requiring the users to have an email address
asking us to allow the users to have our site display the password back to the user just by verifying a Name, Birthday and SSN
emailing the password in plain text as opposed to emailing a temp password and having them come to our site to reset the PW.
requiring we assign simple system generated username like first intial, first 3 characters of the last name with a 4 digit randomly generated number. (as opposed to the user picking any name they want)
If I can present some type of industry standard on why these are such risks it would really help.
Ok, let me answer the suggestions of your Pointy-Haired director (I understood you know he is just wrong, don't take it personally), I just can't resist:
not requiring the users to have an email address
Welcome to fake accounts.
asking us to allow the users to have our site display the password back to the user just by verifying a Name, Birthday and SSN
In my country and culture, privacy is a real concern so you'll never get my SSN and I won't register to any site asking this. BTW, if this is an information that can be found on the web (I've heard it's the case in the US), this doesn't seem really secure. Why not a security question to add some personal entropy?
emailing the password in plain text as opposed to emailing a temp password and having them come to our site to reset the PW.
LOL! First, how would you do this if you don't have the user's email address (and didn't verify it during registration)? Then, being able to send a password back means that you aren't going to store hashes of salted passwords. Bad idea. Is you director planning to store clear passwords (in the worst case) or to use symmetric encryption (in the best case)? In the later case, I'd like to know where he's planning to store the symmetric encryption key. Maybe on a post-it note under his keyboard. Not sure it's worth to mention that email is not secured.
requiring we assign simple system generated username like first initial, first 3 characters of the last name with a 4 digit randomly generated number (as opposed to the user picking any name they want)
Having a system suggesting available usernames is ok (especially when it's hard to find an available one) but I don't like when they don't allow me to choose a username. Having that said, I don't consider forcing a username as a major threat.
So, in other words, I really wouldn't trust a site with such practices and wouldn't give it any sensible information. Actually, I wouldn't give any information at all (i.e. not register) but I'm not the lambda user.
I know this is not a direct answer to the question but, seriously, when will people with absolutely no clue about something start to let people with a better understanding do their work? This is so ridiculous.
Now, some suggestions to answer the question:
The Definitive Guide To Website Authentication (beta)
Best practices for web login / authentication?
The OWASP's Guide to Authentication
The Weak Password Recovery Validation from the WASC Threat Classification
OWasp is specifically designed to contain standards for security, although it has a lot of articles that are too specific for what you want. You might want to try their development guide or ask on their forum the same question.
The W3C has a security group with a load of bumf. It may contain something that you want. The WASC also has a lot of info and looks authorative.

How does hashing and salting passwords make the application secure?

As much as I understand it is a good idea to keep passwords secret from the site administrator himself because he could try to take a user's email and log into his mailbox using the same password (since many users use the same password everywhere).
Beyond that I do not see the point. I know it makes more difficult the dictionary attack but... if someone unauthorized got into the database, isn't it too late to worry about passwords? The guy has now access to all tables in the database and in a position to take all the data and do whatever he wants.
Or am I missing something?
The bigger problem is that people tend to use the same password everywhere. So if you obtain a database of usernames and unsalted passwords, chances are good they might work elsewhere, like hotmail, gmail etc.
The guy might be in a position to do everything he/she wants to your system, but you shouldn't allow him/her to do anything with other systems (by using your users' passwords).
Password is a property of your users. You should keep it safely.
Many of your users use the same credentials (usernames/passwords) at your site as they do at their bank. If someone can get the credentials table, they can get instant access to a bunch of bank accounts. Fail.
If you don't actually store passwords, then attackers can't steal your users' bank accounts just by grabbing the credentials table.
It relies on the fact that a hash is a one way function. In other words, its very easy to convert a password into a hash, but very difficult to do the opposite.
So when a user registers you convert their chosen password into a hash and store it. At a later point they login using their password and you convert the password to its hash and compares it this is because, to a high level of probablity if (passwordhashA == passwordhashB) then passwordA=passwordB.
Salting is a solution to a related problem. If you know that someones passwordhash is, say ABCDEF, then you can try calcuolating hashes for all possible passwords. Sooner or later you may find that hash('dog') = ABCDEF, so you know their password. This takes a very long time, but the process can be speeded up by using pre-created 'dictionaries' where, for a given hash you can look up the corresponding password. Salting, however means that the text that is hashed isnt a simple english word, or a simple combinationofwords. For example, the case I gave above, the text that would be hashed is not 'dog', but is 'somecrazymadeuptextdog'. This means that any readily available dictionary is useless, since the likelyhood of it containing the hash for that text is a lot less than the likelihood of it containing the hash for 'dog' This likelihood becomes even lower if the salt is a random alphanumeric string.
The site admin may not be the only person who gets access to your password. There is always the possibility of a dump of the whole database ending up on a public share by accident. In that case, everybody in the world who has internet access could download it and read the password which was so conveniently stored in cleartext.
Yes, this has happened. With credit card data, too.
Yes, it is highly probable that it will happen again.
"if someone unauthorized got into the database, isn't it too late to worry about passwords?"
You're assuming a poor database design in which the authorization data is comingled with application data.
The "Separation of Concerns" principle and the "Least Access" principle suggest that user credentials should be kept separate from everything else.
For example, keep your user credentials in an LDAP server.
Also, your question assumes that database credentials are the only credentials. Again, the least access principle suggests that you have application credentials which are separate from database credentials.
Your web application username and password is NOT the database username and password. Similarly for a desktop application. The application authentication may not necessarily be the database authentication.
Further, good security suggests that access to usernames and passwords be kept separate from application data. In a large organization with lots of database users, one admin should be "security officer" and handle authentication and authorization. No other users can modify authorization and the security officer is not authorized to access application data.
It's a quick audit to be sure that the security officer never accesses data. It's a little more complex, but another audit can be sure that the folks with data authorization are real people, not aliases for the security officer.
Hashed passwords is one part of a working security policy.
Of course, storing hashes of passwords instead of plain-text does not make your application secure. But it is one measure that increases the security. As you mentioned if your server is comprised this measure won't save you, but it limits the damage.
A chain is only as strong as its weakest link
Hashing passwords is only strengthening one link of the chain. So you will have to do more than that.
In addition to what has already been said regarding salting, there's another problem salting solves :
If you use the same salt everywhere (or no salt at all), it's possible to say just by looking at the database that user foo and user bar both have the same password (even if you don't know what the password is).
Then, if one achieve to get foo's password (using social engineering for example), bar's password is known as well.
Also, if the salt is everywhere the same, one can build up a dictionary dedicated to this specific salt, and then run a brute-force attack using this 'salted' dictionary.
This may be a bit off topic, but once in a while, I notice some websites are not using hashing (for example, when I click the forgot password button, they send me my password in cleartext instead of allowing me to chose another one).
I usually just unsubscribe, because I don't think I can trust a website designed by people not taking the elementary precaution of hashing passwords.
That's one more reason for salting:)
People seem far too complacent about this! The threat isn't some guy with shell access to your system or to the backup media, it could be any script kiddie who can see the unprotected (but dynamic) part of your site(*) and a single overlooked SQL injection threat. One query and suddenly he can log in as any user, or even as an admin. Hashing the passwords make it far less likely that the attacker can log in as any particular user using their password -or- update a record with their own password.
(*) "unprotected" includes any part of the site that can be accessed as a self-registered user. Contrast this to a bank site, for instance, where you must have an existing bank account to gain access to much of the site. An attacker could still open a bank account to gain access to the site, but it would be far easier to send big guys with bigger guns after him when he tries to crack the system.

What's a good alternative to security questions? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
From Wired magazine:
...the Palin hack didn't require any
real skill. Instead, the hacker simply
reset Palin's password using her
birthdate, ZIP code and information
about where she met her spouse -- the
security question on her Yahoo
account, which was answered (Wasilla
High) by a simple Google search.
We cannot trust such security questions to reset forgotten passwords.
How do you design a better system?
The insecurity of so-called "security questions" has been known for a long time. As Bruce Schneier puts it:
The result is the normal security protocol (passwords) falls back to a much less secure protocol (secret questions). And the security of the entire system suffers.
What can one do? My usual technique is to type a completely random answer -- I madly slap at my keyboard for a few seconds -- and then forget about it. This ensures that some attacker can't bypass my password and try to guess the answer to my secret question, but is pretty unpleasant if I forget my password. The one time this happened to me, I had to call the company to get my password and question reset. (Honestly, I don't remember how I authenticated myself to the customer service rep at the other end of the phone line.)
I think the better technique is to just send an e-mail with a link they can use to generate a new random password to the e-mail account the user originally used to register. If they didn't request a new password, they can just ignore it and keep using their old one. As others have pointed out, this wouldn't necessarily have helped Yahoo, since they were running an e-mail service, but for most other services e-mail is a decent authentication measure (in effect, you foist the authentication problem off on the user's e-mail provider).
Of course, you could just use OpenID.
Out-of-band communication is the way to go.
For instance, sending a temporary password in SMS may be acceptable (depending on the system). I've seen this implemented often by telecoms, where SMS is cheap/free/part of business, and the user's cellphone number is pre-registered...
Banks often require a phone call to/from a specific number, but I personally am not too crazy about that....
And of course, depending on the system, forcing the user to come in to the branch office to personally identify themselves can also work (just royally annoy the user).
Bottom line, DON'T create a weaker channel to bypass the strong password requirements.
Having seen a lot of posters suggest email, all I can suggest is DONT use email as your line of defense.
Compromising somebodys email account can be relatively easy. Many web based email services DONT provide any real security either, and even if they offer SSL, its often not default and you are still relying on the weakness of the email password to protect the user ( Which, in turn has a reset mechanism most the time ).
Email is one of the most insecure technologies, and there are good reasons why its a really bad idea to send information like credit card details over them. They're usually transmitted between servers in plaintext, and equally often, between server and desktop client equally unencrypted, and all it takes is a wire sniff to get the reset url and trigger it. ( Don't say I'm paranoid, because banks use SSL encryption for a good reason. How can you trust the 20-200 physical devices on the route have good intentions? )
Once you get the reset data, you can reset the password, and then change your(their) email address, and have permanent control of their account ( it happens all the time ).
And if they get your email account, all they have to do is have a browse through your inbox to find whom you're subscribed with, and then easily reset the password ON ALL OF THEM
So now, using the email based security, can lead to a propogative security weakness!. I'm sure thats beneficial!.
The question being asked Is one I figure is almost impossible to do with software alone. This is why we have 2-factor authentication with hardware dongles that respond to challenges with their own unique private key signature, and only if you lose that are you screwed, and you then have to deal with a human ( oh no ) to get a new one.
It 'depends' on the 'system'.
If you are a Bank or a credit card provider, you have already issued
some physical token to your customer that you can validate against and more.
If you are an ecommerce site, you ask for some recent transactions
-exact amounts, credit card number used et al..
If you are like Yahoo, an automated approach I would use is to send an
activation code via either a phone call or a text message to the cell
phone along with some other basic question and answers.
Jay
Do away with the (in)security questions completely. They're such an obvious security hole that I'm actually a bit surprised that it's taken this long for them to create a serious (well, highly-publicized) incident.
Until they disappear, I'm just going to keep on telling websites which use them that I went to "n4weu6vyeli4u5t" high school...
Have the user enter 3 questions and answers. When they request a reset present them with a drop down of 5 questions, one if which is a random one from the 3 they entered. Then send a confirmation email to actually reset the password.
Of course, nothing is going to be truly "hacker proof".
When users are involved (and mostly when not, too) there is no security; there is only the illusion of security. There's not a lot you can do about it. You could have 'less common' security questions but even they are prone to exploitation since some people put everything out in the public eye.
Secondary channels like email offer a reasonable solution to the problem. If the user requests a password reset you can email them a password reset token. Still not perfect, as others have said, but exploiting this would require the attacker to be somewhere in the line of sight between the website, its MTA and the users MUA. It's technically easy but I suggest that the reality is it's just too much work/risk for them to bother on anyone except very high profile individuals.
Requiring the user to supply SSL or GPG public keys at account creation time will help enormously, but clueless users won't know what those things are let-alone be able to keep their private keys secure and backed up so they don't lose them.
Asking the user to supply a second emergency password (kind of like PIN/PUK on mobile phone SIM cards) could help but it's likely the user would use the same password twice or forget the second password too.
Short answer, you're S.O.L unless you want to educate your users on security and then hit them with a cluestick until they realise that it is necessary to be secure and the slight amount of extra work is not simply there to be a pain in the arse.
Authenticating everything by sending emails is a reasonably effective solution. (although, that might not have been workable for Yahoo in this case :)).
Rather than messing about with security questions or other means to recover passwords, simply respond to password recover requests by sending an email to a predefined email account with an authorisation link. From there you can change passwords, or whatever you need to do (never SEND the password though - you should always store it as a salted hash anyway, always change it. Then if the email account has ben compromised, at least there's some indication to the user that their other services have been accessed)
The true answer is, there isn't a fool proof way to keep hackers out. I hate security questions, but if your going to use them, allow for user defined security questions. As a user, if I must have a security question on a site to set up an account, I really like having the ability to setup my own security question to allow me to ask something that only I know how to answer. It doesn't even have to be a real question in this case. But a users account is then as secure as the stupidity of the user, and the fact that many users will use something like "question?" and "answer!" or something equally dumb. You can't save users from their own stupidity.
Treating these security questions as something actually being two-factor authentication is totally misleading. From spurious items read before, when certain (banks) sites were required to have "two-factor authentication" they started implementing this as a cheap way to do it. Bruce Schneier talked about this a [while back][1].
Multiple factors are best things that are not-the-same. It should not be all things you "know" but something you know and something you have, etc. This is where the hardware authentication tokens, smart cards, and other such devices come into play.
[1]: http://www.schneier.com/blog/archives/2005/03/the_failure_of.html The Failure of Two-Factor Authentication
when its not an email system, email them a link to a secure page, with a hash that must come back in the query string to reset password.
Then if someone tried to reset your password, you would know, and they wouldn't be able to guess the hash potentially.
We use 2 guids multiplied together, represented as hex.
Well for one it should not directly reset the password but send an email with a link to reset the password. That way she would have got the email and known that it was not her who initiated the reset, and that her question / answer had been compromised.
In the case where the email address is no longer valid, it should wait for a timeout ( few days or a week ) before allowing a new email to be attached to an account.
Send a message to a different e-mail account, or text their cell phone, or call them, or send a snail-mail message. Anything that doesn't involve matters of public record or preferences that may change at any time.
Good security questions are a misnomer. They actually create a vulnerability into a system. We should call them in-secure questions. However, recognizing the risk and value they provide, "good" security questions should have 4 characteristics:
1. cannot be easily guessed or researched (safe),
2. doesn't change over time (stable),
3. is memorable,
4. is definitive or simple.
You can read more about this at http://www.goodsecurityquestions.com.
Here's a list of good, fair, and poor security questions.
IMO Secret questions should only be used as a very weak control with a time limit as part of a system.
Ex: Password reset system.
You are authenticated. Registrate your mobile phone number and your secret(not so secret) answer.
You forget your password.
You request to unlock it.
a) Your "Not so secret" question asks you for the "not so secret answer".
b) If correct, a text message is sent to the pre registrated phone.
This way, if your phone gets stolen and also, controls like pin/lock on the phone is not working. You still will have a measure of obfuscation for the attacker to get to reset the password until the time it is reported the phone is lost/stolen and can be disabled.
This usage is what i think the only purpose at all for the "not so secret" questions/answers.
So i would argue there is a place in this world for them and that usually a system needs to be the discussion.
Only provide questions that aren't on the public record.
always send the password reset to a registered email account (which is tricky for an email account) or send a PIN number to a registerd mobile phone, or a link to a IM address, etc - basically, capture some secondary contact information on registration and use it to send a 'password reset' link.
Never let anyone change their password directly, always make sure they go through an additional step.
I prefer to keep things simple and use an honor system approach. For example I'll present the user with something like,
Is this really you? Select: Yes or No.
How about requesting the users to enter their own security question and answer, and a secondary email (not the one where the password reset link is sent). Store the security question and answer hashed in the database for that extra step of security.
If the user forgets his/her password, send the password reset link to the user's primary email.
User then clicks on the link which redirects and asks for the security question and answer. If this step is successful then allow the user to reset his/her password. If the user forgets the security question/answer send a link to reset the security question/answer to the user's secondary email.
If the attacker gets access to one of the emails, it will still be useless without access to the other (very unlikely the attacker can get access to both). I know this process needs a lot of extra work on both the developers and users, but I think it is worth it. (Maybe we could give the users a recommended option to activate the security question/answer if they need this extra bit of security.)
Bottom line is that how strong or weak this system works will depends heavily on the user. The strength of the security question/answer and how well the two emails are "untied" (that is, there is no way of gaining access to one email through the other) will decide this systems strength.
I don't know if there are any problems with this way of doing it, but if any, I'd be happy if anyone could point those out :)
Generate a hash that contains the person's username and password and send it over Https to the user as a file. The user saves the file to disk. It is their responsibility to store this file in a secure location. Alternatively you can send it to their email address but this will result in less security. If the user forgets their login credentials they must then upload this file. Once the server verifies the username and password, they are then presented with a dialog to alter their password.
Due to the evolution of social media, security questions asked by websites are too easy to crack. Since most of the questions are personal information which is easily available on social media platforms one or another. One of the alternatives to avoid account hacking is to make password rules strict for login like adding special characters, numerical, capital letters etc. These kind of passwords are hard to decode and can enhance the security to a great extent.
But there are new alternative methods like multi-factor authentication, passwordless login, SMS authentication etc. SMS authentication is part of multi-factor authentication where a user is provided with an OTP on his/her cellphone which he/she need to enter in order to log in to a website. This is a secure way since the access of mobile is limited to the user only(mostly). Another multi-factor authentication method is sending a verification link to email to complete the signing in process. There is a very well written blog on this topic on Medium that explains this concept in a detailed manner.

Resources