After the whole Heartbleed fiasco, I’ve decided to continue my march towards improving my online security. I’d already begun the process of using LastPass to store my passwords and generate random passwords for each site, but I hadn’t completed the process, with some sites still using the same passwords, and some having less than ideal strength passwords, so I spent some time today improving my password position. Here’s some of the bad examples of password policy I’ve discovered today.
First up we have Live.com. A maximum of 16 characters from the Microsoft auth service. Seems to accept any character though.
This excellent example is from creditexpert.co.uk, one of the credit agencies here in the UK. They not only restrict to 20 characters, they restrict you to @, ., _ or |. So much for teaching people how to protect themselves online.
Here’s Tesco.com after attempting to change my password to “QvHn#9#kDD%cdPAQ4&b&ACb4x%48#b”. If you can figure out how this violates their rules, I’d love to know. And before you ask, I tried without numbers and that still failed so it can’t be the “three and only three” thing. The only other idea might be that they meant “‘i.e.” rather than “e.g.”, but I didn’t test that.
Edit: Here is a response from Tesco on Twitter:
Here’s a poor choice from ft.com, refusing to accept non-alphanumeric characters. On the plus side they did allow the full 30 characters in the password.
The finest example of a poor security policy is a company who will remain nameless due to their utter lack of security. Not only did they not use HTTPS, they accepted a 30 character password and silently truncated it to 20 characters. The reason I know this is because when I logged out and tried to log in again and then used the “forgot my password” option, they emailed me the password in plain text.
I have also been setting up two-factor authentication where possible. Most sites use the Google Authenticator application on your mobile to give you a 6 digit code to type in in addition to your password. I highly recommend you set it up too. There’s a useful list of sites that implement 2FA and links to their documentation at http://twofactorauth.org/.
I realise that my choice LastPass requires me to trust them, but I think the advantages outweigh the disadvantages of having many sites using the same passwords and/or low strength passwords. I know various people cleverer than me have looked into their system and failed to find any obvious flaws.
Remember people, when you implement a password, allow the following things:
- Any length of password. You don’t have to worry about length in your database, because when you hash the password, it will be a fixed length. You are hashing your passwords aren’t you?
- Any character. The more possible characters that can be in your passwords, the harder it will be to brute force, as you are increasing the number of permutations a hacker needs to try.
If you are going to place restrictions, please make sure the documentation matches the implementation, provide a client-side implementation to match and provide quick feedback to the user, and make sure you explicitly say what is wrong with the password, rather than referring back to the incorrect documentation.
There are also many JS password strength meters available to show how secure the inputted passwords are. They are possibly a better way of providing feedback about security than having arbitrary policies that actually harm your security. As someone said to me on twitter, it’s not like “password is too strong” was ever a bad thing.
Maybe for some weird reason Tesco doesn’t recognise ‘%’ as an allowed character?
That did occur to me, which is what I was implying with the i.e. instead of e.g. I find it slightly frustrating when documentation doesn’t match the actual implementation, especially when they don’t give you any clues as to how your password failed.
Although PayPal itself apparently wasn’t vulnerable to Heartbleed, I discovered while switching HTTPS certificates that some versions of the PayPal “checkout” process have a password input box with a limited length, which was too short for my PayPal password… luckily, the front page of the PayPal website does not have that limit, so at least I was able to log in there and change it to something shorter.
 … by paying for StartCom certificate revocation, then paying for certificates from a provider with less damaging revocation policies 🙁
I use a password tool (KeePass) aswell, and wanted to change my PayPall password.
Guess what? They won’t let you paste a new password…
It’s now like I even trying to remember my newly created password…
Note that if you are using a strong password hashing algorithm you may want to limit your passwords to something like a few hundred characters, otherwise grinding your webservers to a halt would become a very easy thing to do: just give it 5 MB worth of data for hashing and your server won’t be doing anything else.
That said, companies clearly need to stop those ridiculous password policies and many probably need to pick way stronger password hashing algorithms.
Yeah, a sane limit is sensible. 20 characters is not sane. 🙂 Someone did suggest 400-600, which seems reasonable.
I’m not sure if it’s still the case, but the last time I checked (last year) ICQ’s password field was limited to eight (8) characters. That’s the worst I’ve ever seen.
I bet the Tesco password thing is something to do with either HTML entities or URL encoding. It’s not hard to test this stuff is clean and working, but few do.
In that Tesco. It appears you have the % symbol which I don’t see in their pre-approved list. Also the %48 could be encoding to a different character due to html issues.
I did consider that, but their statement used ‘e.g.’, which implies a non-exhaustive list. But then following a strict interpretation of their rules, I must have a password that is longer than 8 characters, but can only use three of only one upper case letter, only one lower case letter, only one number and only one special character, which makes me wonder what I’m supposed to use for the other five or more characters. Maybe I shouldn’t assume precise grammar on their part.
They’ve since told me on twitter that I shouldn’t use special characters, which somewhat contradicts their documentation. I’ll test it without shortly.
Two comments. First: good job. I know lots of people who push the boundaries on web sites. If they say they accept 30 characters for a password, my friends use 30 characters. You’ve only scratched the surface. Sometimes the change password page doesn’t accept the full 30, or the sign-up page allows 30, but the actual login form doesn’t. Sometimes there’s truncation so that when you go to change your password, you only type the first 16 of your old password because that’s what they’re actually storing. Go through the full password life cycle at some of these places and you’ll find still more bugs in their implementations.
Second thing: hashing is NOT what we do with passwords any more. We use encryption or hashing in brute-force resistant formulas whose complexity can be increased over time. PBKDF2 for example. Take a look at the OWASP password storage cheat sheet for a comprehensive set of recommendations.
Agree that simple hashing is not the modern technique. I was using it more as a synonym for “not plain text” 🙂 I’ll go investigate that cheat sheet though. Cheers.
This is a tough problem to crack. By choosing a specific password policy you are committing to defending password recovery from specific attacks.
The use of letters, digits and special characters makes it harder to attack passwords by merely testing for combinations of dictionary contents, or just by guessing them.
A minimum length makes it harder to mount brute force attacks.
A maximum length requirement always seems to be a sign that something is not quite right in how the password data is stored or transformed for storage, possibly due to external restrictions. For example, the 8 character password length in Unix systems was related to the limitations of the DES encryption method. In that context, at least the length restriction was “honest” in representing what the underlying security mechanism was capable of.
It is difficult to explain to the user why the rules for choosing a password need to be followed, which makes using password strength meters tempting. They provide immediate feedback, but how does the feedback come about?
For a project of mine I considered adding a password strength meter to the user settings form. Some of these implementations are almost a decade old by now.
The average implementation performs a very basic test in the line of “must contain digits and special characters”. The slightly better ones check for repetition, presence of both lower and upper case characters (which is a crude approximation of the password entropy).
The most recent implementations go so far as to check for specific patterns, such as common passwords (all those leaked password databases were good for something). A few calculate the entropy of the password text (the larger the entropy, the harder it is to recover passwords from a leaked file of hashed text).
There’s the rub: checking for patterns is specific to a language or culture. If your user’s native language is not English, then checking the user’s choice of passwords for common English names, terms or whatever combination of letters on the keyboard the user might hit, will not be helpful.
Then there is the problem of implementation again: the password strength meter which in my eyes seemed to be best equipped to handle password entropy evaluation is written in Coffeescript, but it also has a hard-coded large database of common English language passwords embedded in it (I am talking about “zxcvbn”, which is a project by DropBox, and available on GitHub; see https://tech.dropbox.com/2012/04/zxcvbn-realistic-password-strength-estimation/). For me, half of this functionality is useless (my users are not using English), and I cannot easily adapt the code.
Eventually, the policy on which I settled for my project was to require that the password has to be at least 10 characters long. NIST SP 800-63 suggests that greater length provides for greater entropy, and the 10 character requirement is my best hope to provide for that.
In my project, the user is free to enter any character for a password, it does not have to be a 7 bit ASCII letter. There is, however, an upper limit to how long the password can be. I picked a number around 400-600 characters. Not because this is how much space I need to store the password, but because of the password hash algorithm employed. Algorithms such as bcrypt or PBKDF2 are designed to run slowly, and if you permit arbitrary length password to be submitted, then you are inviting trouble: an attacker might DOS your web site by simply throwing very, very long passwords at the hash algorithm. I believe the Django project introduced a maximum password length in order to mitigate this kind of attack.
I am disappointed in how little choice I had in implementing password security in my project. There is some choice in how to store passwords safely, but there is little effective choice in helping users to pick passwords which are resilient towards common attacks. This includes password strength meters which are typically inadequate for today’s needs and difficult to adapt, to integrate and to verify.
In the end, I decided that rather than providing the user with a false sense of security, I would concentrate on elementary security measures (password length, secure password storage) and allow for the user to make a good choice for picking a safe password. In the input form, the user is told specifically how long the password must be, which characters may be entered, and that there is a large length restriction.
I’d seen “zxcvbn” before, and seemed one of the better ones. I remember seeing their comparison of different strength meters.
I kinda wish OpenId had been more widely implemented. It had the possibility of reducing the number of passwords we needed to worry about. Of course, then we needed to worry considerably more about just one password.
I found that technical solutions to the password problem would create new problems in a different field: culture and language.
For OpenID to succeed, and likewise password management services such as LastPass, the user needs to be aware that there is a problem and a possible solution. That solution needs to make sense, e.g. it ought to be at least as easy to manage your passwords as whatever method you are using right now, and the user needs to be able to trust both the promises and the quality of the service offered.
As developers we may be aware of the problem and the possible solutions, and we may be able to make an informed choice when it comes to pick a solution. How many users outside this circle are able to do this?
Make a little experiment: change the preferred language in your web browser from “English” to a different language, say Dutch or French, then visit the web sites of the OpenID foundation or LastPass. Which language does each the web site use? It will probably be English, or mostly English (clear your cookies and return to the web site; is it still in English?).
It is very well possible that the number of users who do not speak English will be unable to use those password management services. They may not even be aware of the fact that these services exist in the first place.
All this goes to show that the authentication scheme used (passwords and policies) has more than one dimension, and delegating the responsibility to handle it is not necessarily an option.
Web services should NEVER save your plain-text password into their database. It should ALWAYS be MD5 hashed & salted before saving to the server. Also, it doesn’t matter if you use a capital letter or number or symbol, because a SHORT password can always get hacked. The more characters you use, the more difficult it is to brute force or guess a password. Therefore, pass-phrases are the best implementation for a password.
You should not use MD5 hashing for storing passwords. You should use a function like PBKDF2, bcrypt or SHA-2 (SHA-256 or SHA-512), along with a salt. MD5 and SHA-1 should be avoided for new developments. In particular, if you use the linux crypt() function, you should use $5$ or (preferably) $6$.
Pingback: More Password Field Silliness | Irreal
Great article. I agree. And I use Sticky Password as my password manager. http://www.stickypassword.com
Linux support is a must for me, but looks useful for others.
Pingback: Stefan Dunn - How to deter users from signing up.