Best practice - 'forgotten username' process [closed] - security

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 1 year ago.
Improve this question
I've currently been asked to implement a 'forgotten username' functionality on a site I've inherited, and I'm curious what the best practice is for the process. I'm already following best practice for resetting the user's password (by sending an expiring, one use reset link) - but there doesn't seem to be any best practice policy for a forgotten username.
The options I've seen on other sites are:
Input email address and send it - this is the most straightforward, but I'm uncomfortable about sending the username to the email address.
Input email address and send a single use, expiring link which displays the username - but after it's expired or been used, it obviously won't work anymore.
Similar to 2, but merge it with the change password process - if the user forgets their username, they get to see their username, but they have to reset their password too.
The user table doesn't have any other info set up within it (security question, date of birth, etc) - so I can't ask for any of this information without adding it retrospectively. But I'd appreciate any advice or views others have on how they have either implemented it, or how they think it should be implemented :).

I'm not sure if this is really a case of best practise.
I imagine the username comes with an email address built into it? Most websites I've seen usually just ask you to input the email address that is linked to the account, and you'll receive an email containing your username.
It's the responsibility of the user to maintain their email address security. The Username is something that IS public information in most cases. I don't see why you need to focus so much secrecy on it.
What I like to do is..
Alternatively, if the user has forgotten their username, you can ask them to sign in with their email address instead. No emailing around necessary, and the user still needs to know the secret password.

I don't see any issue with option 1 as you will be sending the username to the registered email address, which only the registered user has access to. As you say, this is how other websites do it and it is tried and trusted by many.
I'd see option 2 and 3 as overkill, unless you have key business requirements to implement it this way.

All of the options proposed here are open to security issues. Sending the username to their email opens it up to attackers who could sniff the content of the email.
For a more secure approach you may to implement some multi-factor verification.
Example:
On the form for discovering their username ensure their are multiple inputs (email and dob). The more you add the more secure it will be.
If these inputs are correct then ask the user 2 or more security questions. Don't show the questions as drop downs, show them as text.
Finally if the answers are correct then let allow them to login on a form with their username \ password.
** For even more security insert a step between 1 & 2 which emails a random token to the user which they must click to continue the flow.
I understand for most applications this may seem like overkill but if you are working on something which requires tight security then you must be careful with this sort of flow.
This article discusses Forgot Password but I think it's content is applicable:
https://fishnetsecurity.com/6labs/resource-library/white-paper/best-practices-secure-forgot-password-feature

Related

How maliciously made multiple user registrations are managed on a real world website? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I've notoced lots of websites allow users to register by simply asking their email and password [aside all the other information like name, username, genre etc.]. And the users don't have to do email verification as they register, they simply have a reminder that they should verify their email, but otherwise they can use the website normally. This is very good for UX, since the user can immediately start using a website and not wasting time to do email verifications etc. before he knows whether he will keep using this website or not.
So the question I wanted to ask is the following:
Suppose a malicious user writes a program that will keep registering users with valid usernames and valid(syntactically) emails.
This will eventually cause lost of trouble if not correctly managed:
the database will eventually run out of ids for users
This will create lots of records, thus eating up space
More user records, means more lookup time
So, I'm really curious how all this is managed, if at all.
NOTE: most of websites I'm talking about, do not use CAPTCHA(bad for UX), so they manage the issue in some other way, again, if at all.but neither the solution is to delete the record if the user hasn't confirmed his/her email in a time term. For suppose user looses Internet connection[, or forgets, or anything else] the last day he has to verify email. So the user will loose his/her account and just forget about that website. So this is not a solution. not sure about IP limitations. But suppose that is an Internet cafe and users keep registering. And there are dynamic IPs these days. Is limiting the registration to some amount of time a solution? But how do I know when the last registration occurred if the IP keeps changing. So how is this issue solved?
This is not really an SO problem. This site is more focused on solving issues with actual code rather than ways to solve a generalise problem.
That said, the current patterns seem to be...
Require more information. By having more information, you can de duplicate accounts. That said, in your scenario repeated accounts with the same email address should be easily consolidated. This doesn't prevent bots from registering many accounts with different addresses, but adding more requirements, such as address and phone number make it increasingly differcult to match data sets to your validation.
Validate via email. Contrary to what you suggest, this is still quite common and a good means to weed out genuine users with interest in the site from the chaff.
The other option is a federated authentication service such as Facebook, Twitter, Google+. These provide the UX you seek, but without it being your problem to validate.
From your comments that these changes aren't an option...
Your other option is to look at something server side. This will be along the lines of blocking by IP address. The problem I'd have with this is that the user is unaware, at least with the other options presented the user isn't going to get denied based upon something that happens backend. These measures can still be easily circumvented. An IP block can only be implemented for a short period of time, so the rogue registrations just need to delay long enough or more likely flip between different IP addresses.

Which error message is better when users entered a wrong password? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 7 months ago.
The community reviewed whether to reopen this question 7 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
Is there any differences between the following two error messages from security point of view when users entered a wrong password?
Wrong username or password.
Wrong password.
For example, when you enter a wrong password on the Gmail.com, it will tell you "The username or password you entered is incorrect".
Is there any considerations for security reasons? I think the error message: "The password you entered is incorrect" is more clear to users, And, What's more, it's very easy to check whether a username is exists on the Gmail.com: just click "Can't access your account?" and enter the username. If the username doesn't exists, it will tell you.
The idea is to not give hackers extra information. If you say wrong password, you've told a hacker that they have a correct username, and vice-versa. Although what you've said is true, on some sites it is possible to determine if you've guessed a username via other means.
The easiest and most common phrase to use is:
"You have entered an invalid username or password"
The reasoning behind this is to prevent someone from trying to brute force your account by 'guessing' the password. If the attacker gets an error detailing the password is incorrect, then they could try different passwords until getting it right.
However, if you provide a generic message like the one above, the attacker doesn't know if the user, password or combination of both is correct or not.
Just adding some extra information. OWASP guidelines give you recommendations about this issue
https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html#authentication-and-error-messages
An application should respond with a generic error message regardless
of whether the user ID or password was incorrect. It should also give
no indication to the status of an existing account.
Well, from a different point of view, security-wise, the two messages aren't much different. At least for sites that allow registration. The hacker could always go to the registration page and try to register with the said details. Of course, your website, which was initially secured by ambiguity, will straight away shout "that username is taken!" or "that email is already registered!" and it'd look like at that point security is a myth.
In some contexts you don't want an attacker to be able to guess the existence of an account. So you'll always return the generic error message so that an attacker cannot guess if this account exists or not.
In GMAIL context's, it's probably that gmail doesn't want people mining the existing email addresses to be used by spam robots.
Yourself can decide whether enforcing security is a need in your application, or if you can provide more user-friendly error messages.

Best way for a 'forgot password' implementation? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I'm looking for the best method to implement a "forgot password" feature.
I come out with 2 ideas:
When user click on forgot password, the user is required to key in the username, email and maybe date of birth or last name. Then a mail with temporary password will be sent to the user email account. The user uses the temporary password to login and resets his password.
Similar, but the email would contain a link to let the user reset his password.
Or anyone can suggest me a better and secure way? I'm also thinking to send the temporary password or link, force the user to reset the password within 24 hour, or else the temporary password or link will not be usable. How to do that?
Update: revised in May 2013 for a better approach
The user enters his username and hits "forgot password". I also recommend the option of entering the email address instead of the username, because usernames are sometimes forgotten too.
The system has a table password_change_requests with the columns ID, Time and UserID. When the new user presses the button, a record is created in the table. The Time column contains the time when the user pressed the "Forgot Password" button. The ID is a string. A long random string is created (say, a GUID) and then hashed like a password (which is a separate topic in and of itself). This hash is then used as the 'ID' in the table.
The system sends an email to the user which contains a link in it. The link also contains the original ID string (before the hashing). The link will be something like this: http://www.mysite.com/forgotpassword.jsp?ID=01234567890ABCDEF. The forgotpassword.jsp page should be able to retrieve the ID parameter. Sorry, I don't know Java, so I can't be more specific.
When the user clicks the link in the email, he is moved to your page. The page retrieves the ID from the URL, hashes it again, and checks against the table. If such a record is there and is no more than, say, 24 hours old, the user is presented with the prompt to enter a new password.
The user enters a new password, hits OK and everyone lives happily ever after... until next time!
It all depends on your site and the level of security that you're trying to achieve but the basic process for a web app goes something like the following:
The user navigates to the 'forgot my password' page and enters their username or email (whichever is unique) to request a password reset.
Optionally at this stage you can confirm the request by asking for additional information such as the answer to a predefined security question or their date of birth etc. This extra level stops users receiving emails they didn't request.
Look up the user's account. Save a temporary password (usually a GUID) and timestamp against the account record. Send an email to the user containing the temporary password.
The user either clicks on the link containing the temporary password and the user's identifier in the email or navigates to the 'forgot my password' page and copy & pastes the temporary password and their identifier. The user enters their new password and confirms it.
Look up the user's record and if the current time is within a specified time limit (e.g. 1 hour) of the timestamp saved in step 2 then hash and save the new password. (Obviously only if the temporary passwords match!). Delete the temporary GUID and timestamp.
The principal here is that the user is emailed a temporary password that let's them change their password. The originally stored password (it should be hashed!) is never changed to a temporary password in case the user remembers it.
The original password will never be displayed to the user as it should be hashed and unknown.
Note this process relies entirely on the security of the user's email account. So it depends on the level of security your wish to achieve. This is usually enough for most sites/apps.
Troy Hunt makes some excellent points in his article, Everything you ever wanted to know about building a secure password reset feature. The most relevant excerpts are:
[T]here are two common approaches:
Generate a new password on the server and email it
Email a unique URL which will facilitate a reset process
Despite plenty of guidance to the contrary, the first point is really not where we want to be. The problem with doing this is that it means a persistent password – one you can go back with and use any time – has now been sent over an insecure channel and resides in your inbox.
...
But there’s one more big problem with the first approach in that it makes the malicious lockout of an account dead simple. If I know the email address of someone who owns an account at a website then I can lock them out of it whenever I please simply by resetting their password; it’s denial of service attack served up on a silver platter! This is why a reset is something that should only happen after successfully verifying the right of the requestor to do so.
When we talk about a reset URL, we’re talking about a website address which is unique to this specific instance of the reset process.
...
What we want to do is create a unique token which can be sent in an email as part of the reset URL then matched back to a record on the server alongside the user’s account thus confirming the email account owner is indeed the one attempting to reset the password. For example, the token may be “3ce7854015cd38c862cb9e14a1ae552b” and is stored in a table alongside the ID of the user performing the reset and the time at which the token was generated (more on that in a moment). When the email is sent out, it contains a URL such as “Reset/?id=3ce7854015cd38c862cb9e14a1ae552b” and when the user loads this, the page checks for the existence of the token and consequently confirms the identity of the user and allows the password to be changed.
...
The other thing we want to do with a reset URL is to time limit the token so that the reset process must be completed within a certain duration, say within an hour.
...
Finally, we want to ensure that this is a one-time process. Once the reset process is complete, the token should be deleted so that the reset URL is no longer functional. As with the previous point, this is to ensure an attacker has a very limited window in which they can abuse the reset URL. Plus of course the token is no longer required if the reset process has completed successfully.
He makes many more good points about avoiding information leaks, CAPTCHAs, two-factor authentication, and of course the basic best practices like password hashing. I think it's important to note that I disagree with Troy on the usefulness of security questions, preferring Bruce Schneier's skepticism of the practice:
The point of all these questions is the same: a backup password. If you forget your password, the secret question can verify your identity so you can choose another password or have the site e-mail your current password to you. It's a great idea from a customer service perspective -- a user is less likely to forget his first pet's name than some random password -- but terrible for security. The answer to the secret question is much easier to guess than a good password, and the information is much more public.
I'll go with:
Ask user for email, check email is registered
Generate GUID, and send it to that email
Do not reset password yet
User clicks link, and then have to enter new pass
Reset password only after user is in your site, and have clicked reset button after typing new pass.
Make that GUID expirable within a short time period to make it safer.
When you are sending any information via email, it won't be secure. There are too many ways someone can get it. It would be child's play for a skilled hacker looking to steal your information.
Refrain from sending any personal information like passwords and income information via email as it can become VERY EMBARRASSING for you and your organization if such information was leaked or stolen. Think about security seriously. It just takes that one incident for all the bricks to fall.
As for password retrieval, thoroughly read Forgot Password Best Practices.
The bottom line is that an application
following best practices should allow
a user to reset his own password.
Personal security questions should be
used. The application should not send
email, display passwords, nor set any
temporary passwords.
EDIT: Updated link
As said, it depends on the level of security required, however, if you need a higher level, some novel solutions I have seen include;
Displaying half of the temporary password when the user's identity has been confirmed (security question, email address etc.) then the other half being sent to the email account. If the email account has been compromised, it is unlikely that the same person has also managed to perform a man-in-the middle attack. (Seen on UK Goverment Gateway)
Confirming identity via email and another medium - for example a code sent via text to a registered mobile. (Seen on eBay / PayPal)
For somewhere in between these two extremes implementing security questions may be the way to go as mentioned by DaveG.
If you include an email address with the registration. The "forget password" button sends an email to that email address. It ensures that the information is send to a trusted email.
(Unless the database is hacked, but then nothing is safe).
I would enforce unique email addresses across the accounts.
Then it is a simple matter of sending a link to a temporary page that allows the person to change their password. (allow 24 hours or less)
The user's email account is the weakest link in this scenario.
Here are three very good links that provide information on password resets:
http://jtauber.com/blog/2006/03/20/account_management_patterns/
(Don't let users confirm using GET):http://www.artima.com/forums/flat.jsp?forum=106&thread=152805&start=15&msRange=15
http://fishbowl.pastiche.org/archives/docs/PasswordRecovery.pdf
Hope that helps. They sure helped me understand the issue.
Never email a password to the user. Even if it is auto-generated. Best approach (recommend and used by SANS and others):
On the forgot password page, ask
the email/user id and a NEW password
from the user.
Email a link to the stored email
for that account with an activation
link.
When the user clicks on that link,
enable the new password.
If he doesn't click the link within 24 hours or so, disable the link (so that it does not change the password anymore).
Never change the password without the user consent. It means do not email a new password just because someone clicked on the forgot password link and figured out the account name.

What is the best "forgot my password" method? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Forgot Password: what is the best method of implementing a forgot password function?
I'm programming a community website.
I want to build a "forgot my password" feature.
Looking around at different sites, I've found they employ one of three options:
send the user an email with a link to a unique, hidden URL that allows him to change his password (Gmail and Amazon)
send the user an email with a new, randomly generated password (Wordpress)
send the user his current password (www.teach12.com)
Option #3 seems the most convenient to the user but since I save passwords as an MD5 hash, I don't see how option #3 would be available to me since MD5 is irreversible. This also seems to be insecure option since it means that the website must be saving the password in clear text somewhere, and at the least the clear-text password is being sent over insecure e-mail to the user. Or am I missing something here?
So if I can't do option #1, option #2 seems to be the simplest to program since I just have to change the user's password and send it to him. Although this is somewhat insecure since you have to have a live password being communicated via insecure e-mail. However, this could also be misused by trouble-makers to pester users by typing in random e-mails and constantly changing passwords of various users.
Option #1 seems to be the most secure but requires a little extra programming to deal with a hidden URL that expires etc., but it seems to be what the big sites use.
What experience have you had using/programming these various options? Are there any options I've missed?
4) Crediting their bank account with two random amounts and ask them to enter those in.
5) Snail mail them some new password and ask them to enter it in.
6) Have them text or call some number and enter some value to a phone number with the mobile phone they registered on file.
7) Get out of the password management problem altogether by outsourcing it to OpenID providers like Stack Overflow, Facebook, blog engines, and others are starting to do.
Outside of those, use option #1 or #2 with the added feature that both expire in an hour.
I'm shocked at the upvotes on answers describing #1 and #2 as equivalent. They aren't at all. Sending the user a short term link to change their password is the most convenient, most commonly used, and most secure approach that doesn't involve an out of band interaction (mail, text msg, etc.). A few reasons:
Setting a temporary password via a forgot password link allows users to effectively change a user's password and lock a user out of their account if they know the user's login. With a link, the user simply knows someone is messing around and their access isn't impacted.
The password reset link is only valid for a short period, so there's a very small window for an attacker to strike. And even if they did, the user would know because the reset link would no longer work if the attacker intercepted the link and used it to change the password. If the new assigned password isn't changed by the user immediately, the attacker who intercepted the password can quietly impersonate the user indefinitely. So the big difference is, while a hacker can intercept the reset password link email, if they use the link to change the user's password, the user will know something is wrong because the link won't work and they'll generate another password reset request.
Easier to use - the user simply clicks a link in their email rather than typing a new random password you've generated.
And security questions often make a site less secure, not more - they're another attack vector and often the weakest link. I highly recommend reading The Web Application Hacker's Handbook for an excellent discussion on this topic.
Note that Option #2 also requires you to keep track of the old password and expire the new random password if it isn't used within, say 24 hours.
Otherwise I could annoy you by repeatedly issuing you a new random password -- if you are not near your email you might not know why you cannot log in with your normal password.
Also, please avoid requiring an "identification question". The answers to these questions are typically much easier to guess/lookup than real passwords -- so everybody can identify themselves as me. See the Sarah Palin story for a recent example of how insecure this is.
Options 1 and 2 as insecure as each other.
There. I said it. If the user's email account has been breached, there's no reasonable secure way to do things unless you collect more private data like their address, mother's maiden name - all of which can be guessed.
The best (albeit most annoying) version I have seen is where you need to remember a secret question and a secret answer. It means the user has to remember which question they asked, which, of course, can always be forgotten too!
If they forget the question and you're a "real" company, there's always the option of sending the user a token through the post, with instructions on how to reset all their security... It's very unlikely that a hacker will have access to their real life mail.
A skew on that would be to collect a telephone number when the user created the account. If that existed and they couldn't remember any of their details, you could set up some sort of automated calling system that told them how to reset their details.
And one thing to mention about #2: Don't let the process overwrite the current account password. If that happened anybody could say they forgot any account's password, triggering lots of unwanted password changes.
There's no real difference between the security of option 1 or 2. Option 1 is effectively the same as preloading the new password in the form.
In fact, with the prevalence of phishing attacks, one could argue that encouraging use of option 1 with long URLs could make people less alert about clicking on long mysterious URLs.
Read the OWASP top ten to make sure your method is compliant.
Here is the direct link.
Just a quick note on something not specifically in regards to your question. You mentioned you used MD5 to hash stored passwords. Regardless of whether you choose to use Options 1 or 2 (3 is going to be the least secure as, for obvious reasons), MD5 is a cracked hashing algorithm, and can actually make it fairly easy for hackers to gain access to accounts protected by MD5 hashing.
You can read more about the vulnerability it at the following URL: en.wikipedia.org/wiki/MD5
A better hashing solution would be something like SHA, which is still a stable and secure hashing algorithm. Combined with option #1 or #2, you should have a reasonably secure system in place to protect your users passwords, barring all but the most determined hackers.
Option #1 is probably the best. #3 is insecure (and I also suggest using something stronger than MD5, such as SHA1). Option #2 is not good because it allows any random person to lock you out of your account until you check your email, unless you use a security question. And security questions are often easier to crack than passwords.
Option #1 has a couple of major advantages over #2. If a random user types in my email address into the "I have forgotten my password" box, then my password will not be reset. Also, it is slightly more secure in that there is no permanent record of the site's password stored in your gmail inbox forever.
A critical missing piece here is that the link you provide in #1 should only work for one password reset and have a time limit
All these solutions mean that you are treating your email inbox as the "one ring" that rules them all. Most online services seem to be doing this now days anyway.
My preferred approach is to go with openid where possible. Password management is hell that no one seems to get quite right. It's easier to hand this problem to someone else.
Option 4: Require user to reset password by entering their account name AND email address. As long as you aren't disclosing real names or email addresses on the site (WHY would you in this day and age?) this is a reasonably secure and tamper-proof method. Send a link to a reset page, not the password itself.
Option 5: Use OpenID and pass the responsibility to a 3rd-party to worry about it.
Honestly though this is a lot more effort than most sites require. I for one LIKE receiving plaintext passwords by email because I store them in a "registrations" folder in my inbox. That way I can lookup passwords for sites when I forget them (which happens a lot!). If somebody is reading my email I have bigger problems to worry about than people using my twitter account (if I had one). Of course banks and corporations have stronger requirements but you didn't specify what your site is. That's the key to the best answer.
I agree with your comments about option #3 being insecure.
As for programming either #1 or #2, option #2 is easier to program but #1 isn't much harder and both are probably about as secure as each other.
Whichever option you choose, you can also consider making it more secure by including requests for personal information (that you obtain during registration) as part of the forgotten password process.
I've programmed systems where you have a username and to get a new password you have to enter both your username and your email address. You can get sent a reminder of your username but the main point is that someone probably won't be able to guess your username and your email but if you do it just on email, there's less secure.
Secret questions are an approach to the personal information part. I personally think they don't offer a lot of value as people tend to choose questions that many people will either know the answer to, be able to guess or be able to find out. It is better than nothing however so long as you use it in conjunction with an already relatively secure method.
Obviously the more of this you do, the more programming work it is.
The simplest method is:
Have a "remind me of my username" link (enter email). Don't tell the user if an email was sent or not because people can use that to find out if an email address is of a member. Always tell the user to check their inbox for the reminder email but only send it if someone is a member; and
Require both username and email to get sent a new one-time password. That password should only last an hour or so. When the user uses it, they should be forced to change their password immediately.
Either option 1 or 2 would be fine. As you said, option 3 is insecure as you would need to store the clear text password. You could probably get fancy and use a reversible encryption algorithm to store/retrieve the password, but with better alternatives available to you there's no reason to go down that road.
There is an additional option that you can use in combination with any of the options that you mention:
You can let the user write a reminder for their password, that you send to them as the first step when they have forgotten the password. If the reminder doesn't help the user, you can go on to the next option.
As the reminder isn't the password itself, it's safe to send by mail (or perhaps even display directly on the page).
If you are hashing them Option 3 is unavailable and if you are not hashing them, shame on you. :)
I prefer option 1, sending a reset password link sent to their email which allows them (for a limited time) to reset their password. It does require more work, but it's easy for them to use and ultimately as secure as their email login process.
You could made a mix between #1 and #2, taking advantages from both:
Send the user an email with a link to a unique, hidden URL that allows him to change a new randomly generated password.
That page could be SSL, and the password could expire in 12-24 hours.
I've tried a couple of methods that I've not really been happy with. What I've settled on for the next project is to:
User enters username and email address
Email sent with link containing url and guid param which has been stored in db with 48 hour expiry
User confirms password to be reset
New password is emailed to user
Login with new password displays message or redirects to change password page.
Instruct the user come personally to your offices and prove her identity with id card or passport.
This, of course, assumes that you have offices near your users and that the account are valuable enough to justify this procedure. Suitable for example banks.

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