Monday, April 20, 2015

Password Security Done Right

There's a misconception that passwords are utterly flawed, since most people reuse only a couple across sites.
And there's also a false sense of security as soon as passwords are put into place in an application.

Using passwords is like skating on thin ice: there's so many things that could go wrong and turn a very secure site into a hacker's heaven.


Storage


The best storage is actually one that, if compromised, would not allow the attacker to impersonate a user, on the same application or elsewhere. The ideal solution is therefore to NOT store the password at all, but a derivative, as done in the Secure Remote Password protocol[11].

A less secure yet more common approach is to simply store the said password encoded, using either a hash (one-way) or some encryption (2-way). The former makes it irreversible, which means one *cannot* make out what the password is. The latter is reversible, provided some extra bits of information to do so (a key).

When it comes to authentication, it's enough to compare the encoded value of a provided password vs. the stored one. This is by far the most secure since, if there is a breach, hashed passwords are of little value to anyone, provided passwords are strong enough (discussed further below).

One might use two-way encryption - sometimes a system needs to decrypt one's password (e.g. to use it against other applications).
Even at the same strength level between hash and encryption, this would still be a less secure situation because if someone would gain access to the system, it's very likely one would find his way to the keys necessary for decryption.
This approach is very much flawed and one should look into alternatives (like Secured Delegated Authentication), when possible.


Password Policy


A password policy simply defines what constitutes a password in an application and its uses. This actually goes a long way in term of security. It includes, but is not limited to:
  • Length of password: what's the minimum number of characters it has to be. Any maximum?
  • Composition: upper case, symbols, digits.
  • Expiration: does the password expire at some point? After 60 days, 90 days, more?
  • Reset: can the user requests for his password to be reset? Or does an admin/supervisor have to do that?
  • Temporary: when creating a new password for the user, does the user have to create a new one upon first (re-)login?
  • History: can a user re-use an old password? If not, how far back will the system store old passwords?
  • Max attempts: the maximum numbers of password attempts (usually 3 but it's profoundly arbitrary[1]).
    It's good to mention that implementations should not count repeats as attempts[1].
    Showing password rules help users remember passwords.
    Password hints are a double-edge swords as the system can't really make sure it's just not too obvious (e.g. "13th President of USA").
    After this maximum number of attempts, the user account is usually locked for a certain period of time, usually specified with the following property.
  • Lock backoff: either a strategy (e.g. exponential backoff) or a simple value for a linear backoff strategy (like 5 minutes). Another option is to not have it and have the user "call support" to unlock account (extremely common).

A password policy is usually across an entire site, but for some web sites it could be per account (e.g. multi-tenant service). Therefore it's possible a password policy needs to be persisted and not just be a part of the application configuration.


Password Strength


A password policy implementation will affect the strength of passwords and consequently reflect on some part of the security of an application.

A single-digit password that never expires is not as strong (by far) as a 10-alphanumeric-with-symbols passwords that expires every 30 days.

There are many ways to estimate the entropy (complexity) of a password but no real standards yet to gauge password strength, as far as I know. NIST, US-CERT and IETF all provide a ton of papers and articles on password tips[2], threat models[3], authentication guidelines[4] and more[5].

If the password is stored encoded, then an encryption algorithm with key stretching must be used: this will make a possibly weak password more secure against brute force attack (or at least buy time).


Password Recovery


There are different ways to recover a password: ask supervisor/admin/help desk to do it or
do it yourself (aka self-service).

Help desk has security issues on its own (social engineering attacks for one) but I'll focus on the self-service approach here. This option is very common and it's very often overlooked. It usually works as follows:
  1. User forgot password
  2. System presents text box for user to fill in email address or username
  3. User submits form
  4. System does something
Things can go wrong on so many levels and some implementations out there are just plain wrong.
The consequences may not be severe (no secret-defense-type of information to protect) but the proliferation of such weak level of security can be damaging if users use the same information across sites and applications[10].

We've all seen those (very) bad implementations:
  • Systems sends new password to user without prior confirmation of request.
  • Systems sends temporary password without prior confirmation of request.
It can't get much worse than those two above. It's the best way for anyone to reset anyone's password.
  • System sends current password (with or without confirmation)
This seems better than the previous two implementations and yet it's not. It won't affect rightful owners but it shows that passwords are either stored plain text or encrypted (and can be decrypted).
The real problems with these types of implementation are:
  1. "Requester" may not be human (bot)
  2. "Requester" may not be the "owner" of that email address or username

To address a., CAPTCHA could be used to some extent. In reality, this may not be necessary if b. is addressed appropriately.

To address b., the system should request confirmation from the user. A very common implementation is to send an email informing the user that a password reset request has been made. A link would be provided to initiate the process. That same email should also also contain a disclaimer for the user to notify the system of the illegitimacy of such request ("If you did not made such request.....").
This is a great feature to keep track of potential bots (or evil doers). Reports and alerts can then be put in place to block IP addresses for example and trigger further actions if need be.

Assuming b. has been implemented as above, the behavior of the system is then trivial. When user lands on the site, the system will validate the request (using request parameters) and prompt user for new password information.
This is a sound implementation and if all self-service password resets out there were based on it, the (online) world would already be a safer place.

But there's still a problem with such process: it's "broken". By that I mean it's not continuous. Once the user requested a password reset, he or she will navigate away from the site, waiting for an email to show up in her inbox. This process has been used so many times that we are all accustomed to it, to the point that we may inadvertently open such "Password Reset Requested" email and follow along. But this may not have been originated from the legitimate site and there lies the problem.


A solution to this is to NOT have the user leave the site when going down the path of resetting the password. Microsoft and Google follow that implementation by sending a code to user's phone or through an app (e.g. Microsoft Account App[7]). The system will inform the user that a code has been sent to her device and prompt the user to enter it upon reception. System can then validate the code and continue on with the process.


Not over yet


It might seem obvious that using an app would be safer than storing user's phone number and yet storing phone numbers might turn out to be a necessary evil.

I tackled here only the password aspect but user security goes beyond passwords.
How can one recover her own account after being either hacked or locked somehow? What information should or should not be stored when used to confirm proper ownership?


No comments:

Post a Comment