web application secure forget password implementation - security

I'm designing a web application as an university project, which involve a "forget password" feature. I have read many topic on this and realize that anything depend on email is not secure. Many articles that point out the weaknesses of email-based solutions prefer on-site solutions, such as asking secret question (What is your pet's name, etc.) or 2-step-authentication
For a school project, I can't really afford the 2-steps, or phone number - based implementation. But doing it via on-site solutions doesn't appeal to me, either.
The so-called "secret key", which are answers to these security question, although excellent for security, I think it is terrible for user experience, not only those question's answer can change with time (had a new pet, change favorite food, etc.). But because of the nature of these question, there cannot be constraint on the answer like an actual password. The user will not remember if he typed "cheeseburger", "Cheeseburger", "Cheese Burger" or "Cheese-Burger" for his favorite food.
so I thought of a mechanism that just partly depend on email:
User click forgot password
=> a form will show up, prompt the user to input both Username and Phone, if there are an account that contain both, an error will be
throw, and the user cannot know if "that inputted Username not exist"
or "it exist but the Phone doesnt match"
=> if the the username and the phone was right, I will generate a token AND an OTP code, then I will redirect to a reset password page with the token (?token=aks123hadsh) then send that
OTP code via email
=> On the backend, if both the token and the OTP code are right, the password change will be committed
By this implementation, a hacker who only had access to the victim's email doesnt know what the token is and if he attempt a request by himself to get the token he must know the phone as well
But this implementation still fail if the hacker had access to the victim's email and know both his phone and username
So my question is, is there anyway to improve this implementation, or is this the limit of a non-2-step solution?

Related

Best practices for passwords on registration?

I have a website which users register an account. On the registration field, the form fields are:
Name
Email
Confirm email
Username
But there is no password field. When they hit submit, they are emailed a password which is very complex, such as LHJVjhwnv%uu5 or RbWM9!jeDZUQb.
I have appealed to my developer to instead make it so that the users can set their own password on the registration form. To confirm that password on the form, and then be sent a confirmation link to their specified email. Then this way they can at least log in to their account and verify their email via confirmation link. Or if they didn't, every time they log into the site it could remind them to verify their email etc or else they can't do much on the site (example). This way even if they don't get the confirmation link, they can still update their account email to a different email and have it resent. At least at this stage, they can log into their account, instead of not at all.
The response I have received from the developer is as follows
"The problem with providing the password on registration is that
you'll have loads of fake accounts. So people that just register with
a non-existent email address. At least with the email validation
you're proving the user exists, to a certain extent. If they register with the wrong email, they can just re-register."
I'd like to ask you all if the current approach the developer has employed is acceptable?
If not, what are some good reasons I could use to convince the developer to change?"
I've tried to explain the following
Every day there are 9-10 people who register and then directly use the "password reset" form right after. This form involves them putting in their email address that they signed up with, and then it emails them a link to SET a new password. So if they are setting a new password anyway, why not just have them set it in the first place on the registration form? Why would there be 9-10 people every single day using the password reset field, directly after registration? I'm pretty sure its because they are seemingly struggling with these complex passwords (which I am not against) that are being emailed to them and are missing a key or character, or do not seem to be aware of copy/paste or something like that. If they could just set their own password the first time around, they wouldn't need to run to the password reset field right after because of their emailed password not working. I thought it was weird how everyday theres always password reset emails. Not for everyone, but a good 9-10 people a day ever since I started using Mandrillapp to track the outgoing emails. This is backed up by the next point.
Every day there are at least 2-3 people who fill out the contact form indicating that the password they received is not working. Could all be avoided if they just could set it on their own. There may be even more that just don't bother contacting.
Out of nearly 8000 accounts, 50% have never logged in. My strong suspicion is that the Registration email containing their password goes to their junk folder/spam folder. This is despite me having proper SPF, DKIM, etc setup. 2 months ago, I decided to start using Mandrill to send mail to ensure it goes to the inbox, but still there's at least 1-2 people/day that say that they did not get their email.. which perplexes me. If they could define their own password, they wouldn't have to worry about waiting for their password via email, or not getting it entirely. This just further highlights my initial concern.
Thank you for your time!
I assume you already have a working password-reset page in place, so you can use just the same code to do the registration:
Let the user register with his email.
Send a link with a token to the user, a hash of the token is stored in the database.
If the user clicks the link and if the token is valid, welcome him and let him enter his own password.
This is exactly what you already have for password resetting, your site becomes no more (un)secure because an attacker could as well use the password reset function.
Of course weak passwords are a problem, so rejecting weak passwords is a must. Again this is the same you would have to do on the password-reset page. For password-resets you wouldn't send plaintext passwords neither.
Unconfirmed accounts can be deleted after a certain period, it means the user didn't do anything with it. If necessary the user can register again. This only works if the user is not allowed to login before doing the confirmation, what supports the procedure above. Of course it depends on the website if this confirmation is that important though.
The main reason not to send passwords in a mail is security: Mail isn't a secure medium. If you put a password in there, then many people can see it - consider allowing people to use your service without any kind of password instead to understand what I mean.
The main drawback of allowing people to chose their own password is that 95% will use 123456 or password.
Most big sites use this approach to balance security, business needs and comfort:
Allow user to set their own password. Reject the most simple ones (there are libraries for this). Note: Complex password rules drive customers away.
Send a confirmation link via mail.
Don't allow login until the link has been clicked.
If they try to login anyway, tell them that they have to click the link first plus provide a "send confirmation link again" link in case the first mail was lost.
I have appealed to my developer to instead make it so that the users can set their own password on the registration form....
This opens you up to a plethora of weak password and reuse attacks. Reuse has been empirically studied and reported between 50% and 76%. Other academic studies have stated nearly all users (almost 100%) reuse passwords.
So assigning passwords helps with major practical problems. After you assign the password, then you are subject to the same attack, though because a user may reuse the assigned password on another site.
...
I'd like to ask you all if the current approach the developer has employed is acceptable?
Yes, its acceptable as long as the password meets security requirements. I even prefer it, especially when user selected passwords are not checked against bad password lists.
Bad password lists are important because we know attackers use them. There are literally millions of passwords on them because of all the past breaches (did I mention password reuse is a pandemic problem?). The lists are easy to find, and one researcher recently released his list of 6,000,000+. See How I Collect Passwords.
Aaron is correct about email and plain text. You can actually place another security control to limit the exposure. Namely, require that your mail server use SSL/TLS or fail the connection.
Or, generate the password and display it to the user on the screen. Instruct the user to print the password so they don't forget it. I even tell my users to write them down and keep them in their wallet or purse.
The primary threat is a network based attacker attempting to gain unauthorized access to the server through weak/wounded/bad passwords. So an out-of-band/out-of-channel email is not too great a concern. And a lost wallet or purse is not too great a concern. The concern is the network based attacker guessing passwords or using {username,passwords} tuples from breaches of other sites.
Every day there are 9-10 people who register and then directly use the "password reset" form right after. This form involves them putting in their email address that they signed up with, and then it emails them a link to SET a new password.
OK, that's a security defect since the user can circumvent the security control.
For what its worth, I regularly use a random password generator to generate passwords for accounts. I don't even bother writing them down. When I need to access the account, I simply go through the Lost Password process.
That's how low value these things are to me. Every damn site wants a user to manage an account and password. I'm tired of expending the energy to manage all the accounts, so I don't even waste the cycles on it.
The problem with providing the password on registration is that you'll have loads of fake accounts. So people that just register with a non-existent email address. At least with the email validation you're proving the user exists, to a certain extent. If they register with the wrong email, they can just re-register
OK, so this is a different problem. BOT registrations are usually mitigated with a CAPTCHA. I've never really studied what to use for Real Users/Fake Accounts.
What is the benefit of a fake account? It seems to me the user is trying to get half pregnant. They either have an account, or they don't have an account.
Out of nearly 8000 accounts, 50% have never logged in. My strong suspicion is that the Registration email containing their password goes to their junk folder/spam folder. This is despite me having proper SPF, DKIM, etc setup.
Well, that's a different problem (that you should confirm through testing). This speaks to displaying the password for the user and telling them print the page.
There's a lot more to the subject of password management. You should read Chapter 7 of Peter Gutmann's Engineering Security.
I have appealed to my developer...
Finally, you are the boss. Fire the developer or contractor if they are not following instructions or coding against requirements. I'd be damned before I begged someone who I was paying for services.
Programmers are a dime a dozen, and you can find plenty of them at places like Rent-A-Coder. The Indians and Pakistanis work for next to nothing (under $10 USD per day in some cases). I don't know how they can work for so little and survive...

Failed Validation Messages

Here is the question I have been posed:
"What is the best way to handle in valid credentials when logging into a site. Do we tell the user if their username was invalid? Or likewise if their password is invalid?"
I did some searching, but I'm having trouble finding a site with some best practices for this, to refer them to.
My Question for the community here:
Does anyone here know a site that has some good guidelines/best practices for this?
Just say that their credentials were incorrect.
Telling them that one piece of information was correct means that you're helping hackers discover user names at the very least.
If I enter:
admin
Password1
for example and I get a response that the password was invalid I now know that there is a user called "admin" on you system. I can now just vary the password in an effort to gain access.
If the response was "invalid user name or password" then I'm no wiser about whether there is a user called "admin" or not.
The most authoritative discussion I can find on this issue is from the "Web Security Testing Cookbook," Recipe 12.8.
The book points out:
You should provide a generic message indicating either the username or password was incorrect; revealing that just the username is correct allows attackers to enumerate valid usernames.
Account lockout functionality, after X number of tries, also carries the same risk; attackers can lockout accounts to find out if the usernames were valid or not.
You can read the whole "recipe" via Google Books here:
http://books.google.com/books?id=VmrSJ3V-s_MC&lpg=PA249&ots=cU7V62FQOA&dq=web%20security%20reveal%20valid%20username&pg=PA248#v=onepage&q=web%20security%20reveal%20valid%20username&f=false

sending username and password through email after user registration in web application

What is your opinion on sending the username and password to their email address when they register on our website..this way if they forget the password in the future, they can look it up in their email...also we wont have to implent the forget/reset password scenario (we are close to release)..
is this approach safe enough?
My second question is that basically on our site, the user fills out certain forms and enter some information like their name, address, phone number, income information and such personal information..at the end, when they submit the application, we are thinking of emailing them a summary of all this information like their name, address etc so that they have it for their records..
is this ok..safe enough..what are the concerns
Never send a password or other sensitive information in the clear. That includes e-mail. You should also be storing as little of this as possible in a recoverable format. Unencrypted communication, especially e-mail, is easily tampered with, and you don't want the wrong people getting at passwords.
If possible:
Store your passwords in a salted hash, so the original text is unrecoverable, and thus unbreakable by anything short of a brute force attack. If the user forgets his/her password, make them reset it and send a temporary password (which they are required to change upon login) or a confirmation link (which, again, prompts for a new password) via e-mail.
Never send anything sensitive via e-mail; if the user needs information, make them go to your site to get it. You are using HTTPS, right?
People often share passwords across sites. So you should assume the same password works for the customer's online banking, and you should never send it by e-mail or provide a way for (someone pretending to be) the customer to retrieve it.
It's fine to send them a confirmation e-mail with their username - this is useful.
Remember, if you e-mail them their password they're likely to forget about that e-mail, or just delete it. So you need another password reset mechanism anyway.
The best way to handle the "forgotten password" case is for the user to request you to e-mail the user a link; when they click the link you allow them to type in a new password.
Regarding personal information (address, income etc): why would anyone want this mailed to them? They already know it! You're just sending private data unencrypted over the internet for no reason.
My rule of thumb would be - if you're OK writing it on a postcard and sending it through the mail, then it's OK for standard Email. I don't think income information would fall in that category for most people.
As for passwords, if they can't remember them in the first place, they won't be able to find the Email you sent them with the password in it, and it's an admission of storing it in the clear. I would avoid it and give them the means to reset - they will need that anyway.
The concern is definitely in the sending of the email with the password. If it is not properly encrypted, someone could potentially sniff the packets from the email being sent and recover the password. Also, the person could potentially have a hijacked email account. If it's not a big deal if someone steals the password then you may not have to worry, but otherwise I would NOT send any unencrypted passwords via email.
Edit: To address your second question, I wouldn't even email that. I would instead send a link so that they can easily see their profile/information when they log in.
I tell people to think of email like a postcard -- an employee of any company that handles it between the sender and the recipient can read it.
I agree with the top answer and have this to add: every time I receive a signup confirmation email that contains my password I delete the email and strongly consider never using that web service again. To me, it indicates a lack of security & privacy consciousness.
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...
Most company simply do not include Username password combination due to the security of the external email client. Any numbers of users could brute force or guess the password to the email account of another users which would allow the hacker to view the email of your site. Then the hacker could wreak havoc on your site as well
I'd say providing a forgotten password function will still be vital as not everybody will be guaranteed to keep all there emails (or even be able find them later on)...
I have three rules concerning passwords:
Don’t store passwords in plain text in the database
Why should people trust you with that kind of information? You may only have good intentions, but big companies have failed before, so you're at risk too.
Don’t use password reminders
Password reminders are not worth it. They are easy to guess from people in your entourage and you often forget them. There are better ways to reset a password.
Always offer to send a new password by email
This is the most secure way of retrieving passwords. You should force the user to change the password once logged in with the new password.
As mentioned in comments, you might want to look at OpenID. The most secure way to manage passwords is to eliminate them.
I build an Web Application to send sensitive information by email. It's not UI perfect but it's really secure and working very fine.
There an outlook plugin, API to connect external website and the WebSite.
The concept is the message received in your mailbox are not in clear text. It's an HTML email with a link. You need to click the link to access the content of the email. When it's access one time, the message are destroy.
The message are stock in a crypted database on our side. You can configure a password that are know only by the two part to open the message online, or receive an password (Random 6 number) by SMS.
It's very simple to implement by API.
There is a sample
// https://www.secure-exchanges.com/API.aspx
List<string> files = new List<string>();
files.Add(originalFilePath);
string input = $"{body}";
string inputSubject = $"Your {subject}";
SendMessageAnswer answer = MessageHelper.EncryptMessage(new EncryptMessageArgs(GlobalSettings.bindingSecure, GlobalSettings.serial, GlobalSettings.ApiUser, GlobalSettings.ApiPassword, input, inputSubject + " - to open", recipient1, "", password, null, SecureExchangesSDK.SecureExchanges.SendMethodEnum.onlyEmail, false, true, true, "fr-CA", 1, 5)
{
FilesPath = files
});
if (answer == null || answer.Status != 200)
{
throw new Exception($"Impossible d'envoyé un message : {methodName}");
}

Security risk in exposing email addresses and usernames?

Joomla has a built-in function on its login screen "I've forgotten my user name", so that you can type in your email address and the username is sent to you via email.
I was thinking of changing it so that the username was displayed on screen immediately, without any form of authentication. This would greatly reduce the friction for our users who are returning after a long while, but it would allow anyone to type in any email address and see the associated username (definitely not the other way around though).
Does this create any security risks? Is it a good idea at all?
The current implementation requires the user to own the email address, and read the resulting email, to retrieve the username.
Your implementation lets an attacker know immediately which username is connected to an email address. So if the attacker knows a person's username, it's possible to guess at email addresses.
Worse, suppose the attacker somehow knows the password but not the email address. After successfully guessing an email address, it's a reasonable guess that the password for the email account is similar to the password for your web site. So you've helped the attacker hijack the email account, which may contain more information about additional accounts, and so on.
In general, changing any security-related functionality to make things "easier" than the standard implementation probably incurs a security risk. +1 for researching via SO before implementing!
At first glance, it seems like a "bad idea" because you are allowing anyone to:
verify an account exists
confirm the association between a username and an email address
If usernames and mail addresses are treated as "private" information on your site and not already shared, then I would not implement the username lookup by email feature. In effect you are lowering the security bar by 1 factor:
Currrently, looking up the username requires both email address and the user's full mail credentials (so they can pick up the reply)
After the change, all they need is the mail address.
Perhaps more significantly, you create a privacy issue that would need to be addressed (as mentioned by #SoapBox).
But in reality, your site might already employ "username" as a public handle or nickname. And you may already have users publishing their email in their profiles. If this is the case, the username lookup doesn't leak any new information and you could argue no new security or privacy issues are created.
It would make it all a little too easy though, like publishing the script kiddies guide on how to hack my site:
Get a list of email addresses from your preferred supplier
Come to my self-service mail-to-username translation page and run the list through (simple script for this)
Launch dictionary attack on the site using the resulting list of usernames
Bottom line - I think you are best to leave this feature as-is.
I would say it is a slight security risk for your less savvy users. For a user with a weak password, particularly if it is related to their username or e-mail address, exposing their user name leaves them open to having their account hijacked. Other than that, I can't think of a reason it would be a problem. If the user has good passwords, it shouldn't matter at all.
I guess there is a slight anonymity concern. On a forum for example, I wouldn't want someone who "knows" me to find out my username without me telling them. In this case they could take my e-mail and get it. But whether that is an issue depends on your site and your user base.

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