Taking the Security out of Security Questions

12 Dec 2009
A security system is only as strong as the weakest point and this weakest point tends to be the bit where a human is involved (putting your password on a sticky note attached to your screen, for example). As a programmer, there are some things you just can't protect against, and human failure is one of them (Velociraptors are another). However, developers could at least try to make it a bit harder for people to break into other users' accounts.

I came across the following scenario a few weeks ago when attempting to sign up to a new system. Imagine the scene, you've come up with a really secure password. You're happy that it would take someone a very long time to break such a password, and you haven't noted it down anywhere. Now the website you've signed up to is asking you to enter answers to some security questions in case you forget your password. Questions like "What was the name of your first pet?". You only have 4 different questions to choose from, and you have to pick at least two. It is mandatory to provide an answer.

This scenario is not as far fetched as you might first imagine, behold the following image!

Security Questions that aren

I won't name and shame where this screenshot comes from, but it's from a product that's live and out there in the wild (and I should point out, not associated to anything I've worked on).


If you have any sort of sense at all, you'll see why this is a very bad idea.

All The Hard Work, For Nothing


I really don't know what goes through a developer's head when they come up with things like this. You've built yourself a great web application, you're using salted hashes for the password storage, and you're happy that your users have picked secure passwords.You've not forced some silly password restrictions on people, that actually make it easier to guess passwords. You're feeling pretty happy about it all.

But then you wonder about a certain use case. What happens when someone forgets their password? You've used salted hashes so you have no way to retrieve the original password, which means you'll need users to verify who they are somehow first.

Here is where you have some options,

  1. If a user requests a password reset, simply generate a new password and send it to the email address on file.
  2. Get the user to verify who they are by validating some information you have stored under their account. First line of address, day and month of birth, etc.
  3. Security questions. Get them to fill in some security questions when creating their account, then we can just use that!


Security questions seems to be the popular choice, and the one that I come across on lots of websites. If done right, then it can be a life saver when you've forgotten your pasword, but if done wrong, you might as well give out your password.

The Wrong Way


Simply, it's forcing a set of pre-defined questions on users.For example,

  1. What is your mother's maiden name?
  2. What is your mother's middle name?
  3. What was the name of your first pet?
  4. What was the name of your first school?


Now, think about this for a moment. You're going to allow anyone to "recover" their account and change their password if they answer these simple questions.

Not only have you reduced an attack on the site to a simple dictionary attack (since all those questions require dictionary word/sentence responses) but even worse, if you actually know someone, then you'll probably be able to answer those questions pretty easily. I'm pretty certain I could answer at least 3 of those for most of my friends. You'd also be surprised just how many people grew up with a dog called "Rex" or "Rover", etc.

Also, what if the user has never had a pet? Or their mother doesn't have a middle name? By forcing the questions users can pick from is not only going to irritate people but make it much easier for attackers to just randomly try and break the security questions rather than the password.

The Better Way


Once again, I'm going to stop myself from saying "The Right Way", since there's never going to be a foolproof way to recover someone's account if the password is lost. Every method of account recover has it's drawbacks.

If you're going to go down the security question route, then a much better way is to let the user decide the question themselves. It allows the user to come up with something really cryptic, which only that person would know, yet no one else will. For example,

Q. 2X4B?
A. 523P


Unless you're a fan of Red Dwarf, you wouldn't get the reference that 2X4B is the middle part of Kryten's name, with the end being 523P. Ok, a simple Google search could probably find that out, so probably a bad example, but you get the idea.

Obviously this is still vulnerable to the "human element". A lot of people might choose very simple questions, not realising the implication that they're making it easier for others to get at their account. I've actually seen the following in a live environment before as a custom security question.

Q. My password is "iamawesome"?


Seriously... the mind boggles at what that particular user was thinking. So it may be worth adding a quick notice to remind users that silly questions like that will make their account insecure.

Don't Force Your Users


From a security point of view, allowing someone to recover their account if the password is lost is not a very good idea. The password is there for a reason, to secure the account. If it's lost, then no one should be able to get at the account. Account recovery procedures such as security questions were created purely because of customer service.

Users are only human, and humans forget passwords. It's that simple. Not wanting to lose a customer, you will want to provide a way for a user to recover their account and prove they are who they say they are. If security questions are implemented correctly, then the benefits to customer service far outweight the potential security implications of having two access points to an account, especially if both access points are just as secure as the other.

However, part of customer satisfaction is not to force something on your users. I cannot stand it when I have to sign up for a website and fill in all sorts of information as mandatory, before I'm allowed to continue. By all means provide the user with the ability to create a custom security question, but don't make it mandatory. If a user doesn't want to provide another means to access their account, don't force it on them.

Forcing also has the side effect that most users will just think "Eugh, I just want to continue, I don't care about this" and they'll enter something stupid which is easily breakable. Putting "I don't care" as the answer for example (Yes, I've done this myself).

Adding Salt


It's worth noting that answers to security questions should be treated in exactly the same way as the password. After all, they are effectively the same thing, they both provide the means to access the account in some way. I've seen systems which will store passwords as salted hashes, but then store the security answers in plaintext, completely negating the point of salting the password in the first place. Don't forget to store the security question answers as slated hashes!

Combination Lock


The most effective method of account recovery I've come across is a combination approach. Ask the user to answer their custom security question, and then email a new password to their registered email address. This means unless an attacker knows both the security question answer and has access to the email account, they won't be able to attack the account in this manner. At least not very easily.

Special Case


As with everything, there's always going to be at least one person who manages to lock themselves out of their account, with no access to an old email address and they can't remember their security question response. In these cases it's best not to attempt to provide the user with an automated method for account recovery. Another automated method is yet another point of entry for an account, and another place you need to secure.

In cases like this, it's often better to have a customer service email or phone number which the user can contact, and have a person resolve the issue once they're satisfied the user is who they say they are (by verifying other details on the account).

Get To The Point!


Basically my point is that if you're going to go down the security questions route, don't shoot yourself in the foot. I'm sick of signing up to sites that force me to choose from some security questions before I can proceed. It's the illusion of security, because it actually does nothing except annoy me, and make it easier for an attacker to gain access to my account.

Security questions are great for the user when the password is lost, and they're definitely a nice option. But be sure to take note of the following,

  1. Don't force a certain set of questions on the user. Let them chose their own question.
  2. Don't force a user to fill in the questions as mandatory. If the user doesn't want to, they shouldn't have to. Of course, feel free to ridicule the user if they then forget their password, but it was at least the user's choice.
  3. Hash the answer, and salt the hash before storing.
  4. Don't rely purely on a security question response. Generate a new password and send it to the account email, just so you know it gets to the right person.
  5. If the user doesn't have access to the email, or can't remember the question answer, don't use an automated process. Get another human involved to verify who the person is.


So there you have it. Bought on by my recent voyage into websites that force things on to me, let me know if you've had similar experiences, what methods you use for account recovery (if any) and whether you think anything I've said is wrong. If you have some novel method of account recovery, I'd love to hear about it!


Update


January, 2010 Someone sent me the following image, which are the security questions for a banking website. Another good example of how not to do it.

Even banks fail at security questions.


Only allowing four different questions is a very bad idea. For starters, what if you didn't have a high school mascot? Also most of those questions could be answered by anyone who was a close friend (or enemy). This is not the way to implement security questions, especially not for a bank.

Write a comment

Your comment will be moderated before it will appear on the site.

Tags