The problem with Security Questions
While it may seem that security questions are something that you'd want to implement in your application to provide an additional layer of security, you aren't really adding anything of value to the security of your user's accounts. A study by Google showed that across their very large user base, security questions were largely ineffective at providing additional layers of security, because answers were either:
Question memorability decreases significantly over time. For example the success rate for the question "Favorite Food?" is 74% after a month, 53% after 3 month and barely 47% after a year (Section 4.2).
- Answers were publicly available
Publicly available answers. Rabkin found that 16% of ques- tions had answers routinely listed publicly in online social- networking profiles . Even if users keep data private on social networks, inference attacks enable approximating sen- sitive information from a user’s friends . Other questions can be found in publicly available records. For example, at least 30% of Texas residents’ mothers’ maiden names can be deduced from birth and marriage records .
- Answers were statistically common enough they could be guessed quickly
Statistical attacks against secret questions are a real risk be- cause there are commons answers shared among many users. For example using a single guess an attacker would have a 19.7% success rate at guessing English-speaking users’ an- swers for the question "Favorite food?" ... With 10 guesses an attacker would be able to guess 39% of Korean-speaking users’ answers to "City of birth?" (Section 3.1).
Additionally, if you suffer a data breach, and the answers to the questions leak, you're in for a heap of bad press (quote from wired.com article below):
"Sorry, but if you have a Yahoo account, you will need to find a new mother, and have grown up on a different street," University of Pennsylvania computer scientist Matt Blaze quipped on Twitter after Yahoo's data breach announcement.
A better UX solution
Since you are already relying on the assumption that a user must have access to their registered email address to reset their password (by sending them a temporary plaintext password), you are better off nixing the security questions altogether, and move to a token based reset process. To the user the password reset process should look something like this:
- User forgets password, and submits email in forgotten password form
- User gets email with a password reset link
- User clicks on password reset link and is presented with a password reset form
- User enters new desired password in form and submits
- User logs into application with new password
On the backend, your application should do the following:
- When a user submits a "forgot password" request:
a. Application generates a random token and an expiration timestamp and stores them in the database
b. Application sends an email to the user with the random token and account identifier (email or id, for example) in the reset link as URL parameters
- Account identifier and reset token are placed into hidden form fields on the reset form
- User submits reset form:
a. Application checks that the reset token matches the one stored in the database for that specific account identifier
b. Application checks that current time is not after the expiration timestamp for the reset token
c. Application hashes the submitted password and stores it in the database
d. (optional, but good practice) Application stores a timestamp and other identifying information on the request that submitted the password reset
From a user's perspective, this is a much more usable system. They only have to know the email address they registered with, and the technical security of the reset process (time-bound, long, randomly generated reset tokens) is abstracted away into something they don't need to interact with. You are better off because you are storing less personally identifiable data (a concern with GDPR coming in force next year), you don't need to have users contact customer service to try to identify themselves another way.
If account security and additional verification are big concerns for you, then you should take the time to implement a second, out of band verification, such as a recovery email address or phone number for SMS delivery of a second token.
Secrets, Lies, and Account Recovery:
Lessons from the Use of Personal Knowledge Questions at Google - Google
Time To Kill Security Questions — Or answer them with lies - Wired
7 Reasons Why Password Recovery Questions Are Worse Than Useless - Dashlane