Monthly Archives: December 2016

Security Questions are Bullshit


I’m pretty much unhappy with the use of “Security Questions” – things like “what’s your mother’s maiden name”, or “what was your first pet”. These questions are sometimes used to strengthen an existing authentication control (e.g. “you’ve entered your password on a device that wasn’t recognised, from a country you normally don’t visit – please answer a security question”), but far more often they are used as a means to recover an account after the password has been lost, stolen or changed.


I’ve been asked a few times, given that these are pretty widely used, to explain objectively why I have such little disregard for them as a security measure. Here’s the Too Long; Didn’t Read summary:

  1. Most questions are equivalent to a low-entropy password
  2. Answers to many of these questions can be found online in public documents
  3. Answers can be squeezed out of you, by fair means or foul
  4. The same questions – and answers – are shared at multiple sites
  5. Questions (and answers) don’t get any kind of regulatory protection
  6. Because the best answers are factual and unchanging, you cannot change them if they are exposed

Let’s take them one by one:

Questions are like a low-entropy password

What’s your favourite colour? Blue, or Green. At the outside, red, yellow, orange or purple. That covers most people’s choices, in less than 3 bits of entropy.

What’s your favourite NBA team? There’s 29 of those – 30, if you count the 76ers. That’s 6 bits of entropy.

Obviously, there are questions that broaden this, but are relatively easy to guess with a small number of tries – particularly when you can use the next fact about Security Questions.

The Answers are available online

What’s your mother’s maiden name? It’s a matter of public record.

What school did you go to? If we know where you grew up, it’s easy to guess this, since there were probably only a handful of schools you could possibly have attended.

Who was your first boyfriend/girlfriend? Many people go on about this at length in Facebook posts, I’m told. Or there’s this fact:

You’ll tell people the answers

What’s your porn name? What’s your Star Wars name? What’s your Harry Potter name?

All these stupid quizzes, and they get you to identify something about yourself – the street you grew up on, the first initial of your secret crush, how old you were when you first heard saxophones.

And, of course, because of the next fact, all I really have to do is convince you that you want a free account at my site.

Answers are shared everywhere

Every site that you visit asks you variants of the same security questions – which means that you’ll have told multiple sites the same answers.

You’ve been told over and over not to share your password across multiple sites – but here you are, sharing the security answers that will reset your password, and doing so across multiple sites that should not be connected.

And do you think those answers (and the questions they refer back to) are kept securely by these various sites? No, because:

Questions & Answers are not protected like passwords

There’s regulatory protection, under regimes such as PCI, etc, telling providers how to protect your passwords.

There is no such advice for protecting security questions (which are usually public) and the answers to them, which are at least presumed to be stored in a back-end database, but are occasionally sent to the client for comparison against the answers! That’s truly a bad security measure, because of course you’re telling the attacker.

Even assuming the security answers are stored in a database, they’re generally stored in plain text, so that they can be accessed by phone support staff to verify your answers when you call up crying that you’ve forgotten your password. [Awesome pen-testing trick]

And because the answers are shared everywhere, all it takes is a breach at one provider to make the security questions and answers they hold have no security value at all any more.

If they’re exposed, you can’t change them

There’s an old joke in security circles, “my password got hacked, and now I have to rename my dog”. It’s really funny, because there are so many of these security answers which are matters of historical fact – while you can choose different questions, you can’t generally choose a different answer to the same question.

Well, obviously, you can, but then you’ve lost the point of a security question and answer – because now you have to remember what random lie you used to answer that particular question on that particular site.

And for all you clever guys out there…

Yes, I know you can lie, you can put in random letters or phrases, and the system may take them (“Your place of birth cannot contain spaces” – so, Las Vegas, New York, Lake Windermere are all unusable). But then you’ve just created another password to remember – and the point of these security questions is to let you log on once you’ve forgotten your password.

So, you’ve forgotten your password, but to get it back, you have to remember a different password, one that you never used. There’s not much point there.

In summary

Security questions and answers, when used for password recovery / reset, are complete rubbish.

Security questions are low-entropy, predictable and discoverable password substitutes that are shared across multiple sites, are under- or un-protected, and (like fingerprints) really can’t be changed if they become exposed. This makes them totally unsuited to being used as password equivalents in account recovery / password reset schemes.

If you have to implement an account recovery scheme, find something better to use. In an enterprise, as I’ve said before, your best bet is to use something that the enterprise does well – the management hierarchy. Every time you forget your password, you have to get your manager, or someone at the next level up from them, to reset your password for you, or to vouch for you to tech support. That way, someone who knows you, and can affect your behaviour in a positive way, will know that you keep forgetting your password and could do with some assistance. In a social network, require the

Password hints are bullshit, too

Also, password hints are bullshit. Many of the Adobe breach’s “password hints” were actually just the password in plain-text. And, because Adobe didn’t salt their password hashes, you could sort the list of password hashes, and pick whichever of the password hints was either the password itself, or an easy clue for the password. So, even if you didn’t use the password hint yourself, or chose a really cryptic clue, some other idiot came up with the same password, and gave a “Daily Express Quick Crossword” quality clue.

How to do password reset

First, a quick recap:

Credentials include a Claim and a Proof (possibly many).

The Claim is what states one or more facts about your identity.

A Username is one example of a Claim. So is Group Membership, Age, Eye Colour, Operating System, Installed Software, etc…

The Proof is what allows someone to reliably trust the Claim is true.

A Password is one example of a Proof. So is a Signature, a Passport, etc…

Claims are generally public, or at least non-secret, and if not unique, are at least specific (e.g. membership of the group “Brown eyes” isn’t open to people with blue eyes).

Proofs are generally secret, and may be shared, but such sharing should not be discoverable except by brute force. (Which is why we salt passwords).

Now, the topic – password resets

Password resets can occur for a number of reasons – you’ve forgotten your password, or the password change functionality is more cumbersome than the password reset, or the owner of the account has changed (is that allowable?) – but the basic principle is that an account needs a new password, and there needs to be a way to achieve that without knowledge of the existing password.

Let’s talk as if it’s a forgotten password.

So we have a Claim – we want to assert that we possess an identity – but we have to prove this without using the primary Proof.

Which means we have to know of a secondary Proof. There are common ways to do this – alternate ID, issued by someone you trust (like a government authority, etc). It’s important in the days of parody accounts, or simply shared names (is that Bob Smith, his son, Bob Smith, or his unrelated neighbour, Bob Smith?) that you have associated this alternate ID with the account using the primary Proof, or as a part of the process of setting up the account with the primary Proof. Otherwise, you’re open to account takeover by people who share the same name as their target.

And you can legally change your name.

What’s the most common alternate ID / secondary Proof?


Pretty much every public web site relies on the use of email for password reset, and uses that email address to provide a secondary Proof.

It’s not enough to know the email address – that’s unique and public, and so it matches the properties of a Claim, not a Proof, of identity.

We have to prove that we own the email address.

It’s not enough to send email FROM the email address – email is known to be easily forged, and so there’s no actual proof embodied in being able to send an email.

That leaves the server with the prospect of sending something TO the email address, and the recipient having proved that they received it.

You could send a code-word, and then have the recipient give you the code-word back. A shared secret, if you like.

And if you want to do that without adding another page to the already-too-large security area of the site, you look for the first place that allows you to provide your Claim and Proof, and you find the logon page.

By reusing the logon page, you’re going to say that code-word is a new password.

[This is not to say that email is the only, or even the best, way to reset passwords. In an enterprise, you have more reliable proofs of identity than an email provider outside of your control. You know people who should be able to tell you with some surety that a particular person is who they claim to be. Another common secondary identification is the use of Security Questions. See my upcoming article, “Security Questions are Bullshit” for why this is a bad idea.]

So it’s your new password, yes?

Well, yes and no. No, actually. Pretty much definitely no, it’s not your new password.

Let’s imagine what can go wrong. If I don’t know your password, but I can guess your username (because it’s not secret), I can claim to be you wanting to reset your password. That not only creates opportunity for me to fill your mailbox with code-words, but it also prevents you from logging on while the code-words are your new password. A self-inflicted denial of service.

So your old password should continue working, and if you never use the code-word, because you’re busy ignoring and deleting the emails that come in, it should keep working for you.

I’ve frequently encountered situations in my own life where I’ve forgotten my password, gone through the reset process, and it’s only while typing in the new password, and being told what restrictions there are on characters allowed in the new password, that I remember what my password was, and I go back to using that one.

In a very real sense, the code-word sent to you is NOT your new password, it’s a code-word that indicates you’ve gone the password reset route, and should be given the opportunity to set a new password.

Try not to think of it as your “temporary password”, it’s a special flag in the logon process, just like a “duress password”. It doesn’t replace your actual password.

It’s a shared secret, so keep it short-lived

Shared secrets are fantastic, useful, and often necessary – TLS uses them to encrypt data, after the initial certificate exchange.

But the trouble with shared secrets is, you can’t really trust that the other party is going to keep them secret very long. So you have to expire them pretty quickly.

The same is true of your password reset code-word.

In most cases, a user will forget their password, click the reset link, wait for an email, and then immediately follow the password reset process.

Users are slow, in computing terms, and email systems aren’t always directly linked and always-connected. But I see no reason why the most usual automated password reset process should allow the code-word to continue working after an hour.

[If the process requires a manual step, you have to count that in, especially if the manual step is something like “contact a manager for approval”, because managers aren’t generally 24/7 workers, the code-word is going to need to last much longer. But start your discussion with an hour as the base-point, and make people fight for why it’ll take longer to follow the password reset process.]

It’s not a URL

You can absolutely supply a URL in the email that will take the user to the right page to enter the code-word. But you can’t carry the code-word in the URL.

Why? Check out these presentations from this year’s Black Hat and DefCon, showing the use of a malicious WPAD server on a local – or remote – network whose purpose is to trap and save URLs, EVEN HTTPS URLs, and their query strings.

Every URL you send in an email is an HTTP or HTTPS GET, meaning all the parameters are in the URL or in the query string portion of the URL.

This means the code-word can be sniffed and usurped if it’s in the URL. And the username is already assumed to be known, since it’s a non-secret. [Just because it’s assumed to be known, don’t give the attacker an even break – your message should simply say “you requested a password reset on an account at our website” – a valid request will come from someone who knows which account at your website they chose to request.]

So, don’t put the code-word in the URL that you send in the email.

Log it, and watch for repeats, errors, other bad signs


I have to say that, because otherwise people do that, as obviously wrong as it may seem.

But log the fact that you’ve changed a password for that user, along with when you did it, and what information you have about where the user reset their password from.

Multiple users resetting their password from the same IP address – that’s a bad sign.

The same user resetting their password multiple times – that’s a bad sign.

Multiple expired code-words – that’s a bad sign.

Some of the bad things being signaled include failures in your own design – for instance, multiple expired code-words could mean that your password reset function has stopped working and needs checking. You have code to measure how many abandoned shopping carts you have, so include code that measures how many abandoned password reset attempts you have.

In summary, here’s how to do email password reset properly

  1. Consider whether email is an appropriately reliable secondary proof of identification.
    1. A phone call from the user, to their manager, followed by the manager resetting the user’s password is trustworthy, and self-correcting. A little slow and awkward, but stronger.
    2. Other forms of identification are almost all stronger and more resistant to forgery and attack than email.
    3. Bear in mind that, by trusting to email, you’re trusting that someone who just forgot their password can remember their other password, and hasn’t shared it, or used an easily-guessed password.
  2. When an account is created, associate it with an email address, and allow & encourage the validated account holder to keep that updated.
  3. Allow anyone to begin a password reset process – but don’t allow them to repeatedly do so, for fear of allowing DoS attacks on your users.
  4. When someone has begun a password reset process, send the user a code-word in email. This should be a random sequence, of the same sort of entropy as your password requirements.
    1. Encoding a time-stamp in the code-word is useful.
    2. Do not put the code-word in a URL in the message.
    3. Do not specify the username in the message, not even in the URL.
  5. Do not change the user’s password for them yet. This code-word is NOT their new password.
  6. Wait for up to an hour (see item 4.1. – the time stamp) during which you’ll accept the code-word. Be very cautious about extending this period.
  7. The code-word, when entered at the password prompt for the associated user, is an indication to change the password, and that’s ALL it can be used for.
  8. Allow the user to cancel out of the password change, up to the point where they have entered a new password and its verification code and hit OK.

And here’s how you’re going to screw it up (don’t do these!)

  • You’ll use email for password resets on a high-security account. Email is relatively low-security.
  • You’ll use email when there’s something more reliable and/or easier to use, because “it’s what everyone does”.
  • You’ll use email to an external party with whom you don’t have a business relationship, as the foundation on which you build your corporate identity tower of cards.
  • You won’t have a trail of email addresses associated with the user, so you don’t have reason to trust you’re emailing the right user, and you won’t be able to recover when an email address is hacked/stolen.
  • You’ll think the code-word is a new password, leading to:
    • Not expiring the code-word.
    • Sending passwords in plain-text email (“because we already do it for password reset”).
    • Invalidating the user’s current password, even though they didn’t want it reset.
  • You’ll include the credentials (username and/or password) in a URL in the email message, so it can be picked up by malicious proxies.
  • You’ll fail to notice that someone’s DoSing some or all of your users by repeatedly initiating a password reset.
  • You’ll fail to notice that your password reset process is failing, leading to accounts being dropped as people can no longer get in.
  • You won’t include enough randomness in your code-word, so an attacker can reset two accounts at once – their own, and a victim’s, and use the same code-word to unlock both.
  • You’ll rely on security questions
  • You’ll use a poor-quality generation on your code-words, leading to easy predictability, reuse, etc.
  • You won’t think about other ways that your design will fail outside of this list here.

Let the corrections begin!

Did I miss something, or get something wrong? Let me know by posting a comment!