Password Rules Don't Always Help
A while ago, I wrote about how users can't be trusted to come up with good passwords, and that it's up to us as programmers and web developers to hash the password (and salt it) so that it means bad password choices aren't immediately obvious to someone who gets hold of your stored data.
Of course, if people still use dictionary words, a simple brute force attack will work. So while some password tips such as "Don't use a dictionary word" are quite legitimate, there are plenty of rules and restrictions that do nothing but infuriate users and make passwords less secure.
There is absolutely no need to enforce certain password rules which seems to be forced on people throughout the corporate world and on many websites. Here are a few which I find the most annoying, supposedly implemented to make people use passwords which are more "secure", but in reality do just the opposite. Passwords become more predictable and expert users who create complex passwords get infuriated when they're force to make them less complex in order to fit with the restrictions. I wonder how many of you have come across these before.
Usually it's every 30 days, so that each month you have to have a new password. There are then crazy rules, like you can't use a password you've used the last 12 times. Sure, if someone discovers a user's password, and waits a month to use it, it will no longer work.. but that's pretty much the only case this protects against. But it does a lot more harm.
If you force a user to change their password every 30 days, there's very little chance they are going to come up with a truly unique password each time. Instead, they'll tend to keep the same basic password and just add something extra in. You'd be shocked at just how many people use the name or number of the month as that extra thing.
Since we now know a likely part of the password, it can make it a bit easier to crack with brute force attacks. It could even mean if you do discover a user's password, and it has a number or name of the month.. you'll always know that users password for any month, making this measure completely pointless.
To add further annoyance to this, a lot of system adminitrators feel it's necessary to remind users that they'll soon need to change their password. So 14 days before your password expires in Windows for example, you'll get a popup saying "Your password expires in 14 days, do you want to change it now?" This has to be the most useless dialog I've ever come across. If my password expires in 14 days, why would I want to change it sooner? It makes no sense. Just tell me when it's expired and I'll change it. Making me select Yes or No every single time I login just irritates me.
How many websites or applications have you come across with ridiculous password restrictions like this? I see it all the time. Well.. maybe not the dog one. Yet it doesn't actually do anything to make the password more secure! Forcing users to use a certain pattern, means that an attacker also knows the expected pattern, reducing their search space from "anything in the world" to "well, now I know there's at least two digits and will be mixed case".
I've also seen things like "You must choose a password of the form XxxxxxN" where X is an uppercase letter, x is a lowercase letter and N is a digit. Now, that has to be one of the worst. You've given an attacker everything they need to crack the passwords in no time at all using a simple brute force approach.
Not only does it make attacks easier, but it's more frustrating for users. As I said in the previous post, most users will use the same password for everything. It's not their fault, it's just easier to remember one password than one hundred. If you suddenly force a policy that means users can't use that password, they'll have to come up with a new one, and they'll inevitably forget it, frustrating the user even more the next time they login. Some would argue this is a good thing, but I think if a user has a sufficiently complex password, they should be able to use it everywhere if they really want to (although if they really value security, they'll use a different one everywhere, that's a choice the user should make).
So you're 0 for 2. You've made it easier for attackers and pissed off your users, well done!
Yes, I have actually seen this in a live environment before. If you have someone on your team who insists on using this method, take them into a room and slap them. This is a pretty big mistake since you've given away another users password. Usernames are much easier to find out that passwords, especially if it's a public website.
I'm really trying hard to imagine what was going through the designer/programmers head when they thought of using this technique. There is no need for a system to enforce unique passwords between users.. none at all! If your database model uses a password as a primary key, you have failed as a developer.
Why do you care what I use in my password? As long as it's a character understood by the computer, and as long as it will be hashed the same way each time, you shouldn't care what people use. Restricting the use of special characters is on par with dictating the exact format. It's usually done because of some limitation to the system, that you can't store those characters in the database, it will mess up their admin area, or the website doesn't support multibyte characters, etc. Which means either you're not sanitizing your inputs properly, aren't using prepared statemens and probably don't hash your passwords. Alarm bells should be ringing.
If I want to use a percentage sign or a Japanese character in my password, I should be able to do so. It will mean my password is harder for anyone else to guess. I cannot stand it when I come up with a really complex password like "l-.(mR{n<Pg1$Yh=u'C?^Wp_$ANNn'4gE+?@VE" and am told that my password can only contain letters and numbers. You're forcing me to choose a password that is much less secure than one I've chosen myself. That is unacceptable.
Why not? The most common excuse for something like this, is that the database can only store 16 chars in the field, or that a designer only wants the input box to be a certain size.
Well, the designers argument is nonsense, since they can size the box however they want without restricting the amount of information that can be input. The database excuse is also nonsense, since you should be hashing passwords, so that they'll always be the same length after hashing anyway. So the password itself can be any length you want, yet you only have to store the 40 character hash output (or however many characters you force the hash to be).
A limit can be enforced, but it should be at least 100 characters at the minimum.
If I want to type a novel as my password, then that should be my choice. Restricting password length just restricts the search space an attacker needs to use and infuriates users who actually pick long complicated passwords by making them pick something less secure.
Enforce some complexity if you have to, but don't restrict complexity. I should make it clear that I'm not against all password restrictions. It can depend on the environment. If you're storing the password for a system which has personal data, then enforcing a certain amount of complexity in the password is probably a good idea. I guess the point I'm trying to make though, is that it's easy to go too far. There's a point when it just becomes a hinderance to users, and ends up creating patterns which make the system less secure.
Try not to restrict user password choice. By heavily restricting what a user can enter as a password you're simply annoying your users and making it easier for an attacker to guess or brute force the password. By enforcing too many password restrictions you are making the system more predictable, and when it comes to passwords (and cryptography in general), predictability is a very bad thing.
It comes down to some very simple points.
If you follow these simple rules, your users will be happier, your database will always store the same length of data no matter what the user enters and you can be safe in the knowledge that you're not giving away any information to make it easier for an attacker.
Update (December, 2009): The best method I've seen recently is simply a blacklist of common passwords and dictionary words (this is the method Twitter use apparently). Users can pick a password of any length, with any characters they want and don't have to change it at any interval. They just can't use a common password or dictionary word found in the blacklist. Simple, effective and only reduces the search space by the common dictionary words which would've been easy to crack using brute force anyway.
Of course, if people still use dictionary words, a simple brute force attack will work. So while some password tips such as "Don't use a dictionary word" are quite legitimate, there are plenty of rules and restrictions that do nothing but infuriate users and make passwords less secure.
There is absolutely no need to enforce certain password rules which seems to be forced on people throughout the corporate world and on many websites. Here are a few which I find the most annoying, supposedly implemented to make people use passwords which are more "secure", but in reality do just the opposite. Passwords become more predictable and expert users who create complex passwords get infuriated when they're force to make them less complex in order to fit with the restrictions. I wonder how many of you have come across these before.
The Rotating Password
"You must change your password every x days"
Usually it's every 30 days, so that each month you have to have a new password. There are then crazy rules, like you can't use a password you've used the last 12 times. Sure, if someone discovers a user's password, and waits a month to use it, it will no longer work.. but that's pretty much the only case this protects against. But it does a lot more harm.
If you force a user to change their password every 30 days, there's very little chance they are going to come up with a truly unique password each time. Instead, they'll tend to keep the same basic password and just add something extra in. You'd be shocked at just how many people use the name or number of the month as that extra thing.
Since we now know a likely part of the password, it can make it a bit easier to crack with brute force attacks. It could even mean if you do discover a user's password, and it has a number or name of the month.. you'll always know that users password for any month, making this measure completely pointless.
To add further annoyance to this, a lot of system adminitrators feel it's necessary to remind users that they'll soon need to change their password. So 14 days before your password expires in Windows for example, you'll get a popup saying "Your password expires in 14 days, do you want to change it now?" This has to be the most useless dialog I've ever come across. If my password expires in 14 days, why would I want to change it sooner? It makes no sense. Just tell me when it's expired and I'll change it. Making me select Yes or No every single time I login just irritates me.
The Ridiculous Restriction
Your password must be at least 6-8 characters long, contain uppercase and lowercase letters, and have at least two digits, but not for the first two characters. Oh, and it shouldn't contain the name of a species of dog.
How many websites or applications have you come across with ridiculous password restrictions like this? I see it all the time. Well.. maybe not the dog one. Yet it doesn't actually do anything to make the password more secure! Forcing users to use a certain pattern, means that an attacker also knows the expected pattern, reducing their search space from "anything in the world" to "well, now I know there's at least two digits and will be mixed case".
I've also seen things like "You must choose a password of the form XxxxxxN" where X is an uppercase letter, x is a lowercase letter and N is a digit. Now, that has to be one of the worst. You've given an attacker everything they need to crack the passwords in no time at all using a simple brute force approach.
Not only does it make attacks easier, but it's more frustrating for users. As I said in the previous post, most users will use the same password for everything. It's not their fault, it's just easier to remember one password than one hundred. If you suddenly force a policy that means users can't use that password, they'll have to come up with a new one, and they'll inevitably forget it, frustrating the user even more the next time they login. Some would argue this is a good thing, but I think if a user has a sufficiently complex password, they should be able to use it everywhere if they really want to (although if they really value security, they'll use a different one everywhere, that's a choice the user should make).
So you're 0 for 2. You've made it easier for attackers and pissed off your users, well done!
The Giveaway
"You cannot use that password because another user already has it"
Yes, I have actually seen this in a live environment before. If you have someone on your team who insists on using this method, take them into a room and slap them. This is a pretty big mistake since you've given away another users password. Usernames are much easier to find out that passwords, especially if it's a public website.
I'm really trying hard to imagine what was going through the designer/programmers head when they thought of using this technique. There is no need for a system to enforce unique passwords between users.. none at all! If your database model uses a password as a primary key, you have failed as a developer.
The Normalizer
"Your password cannot contain special characters, only normal letters and numbers"
Why do you care what I use in my password? As long as it's a character understood by the computer, and as long as it will be hashed the same way each time, you shouldn't care what people use. Restricting the use of special characters is on par with dictating the exact format. It's usually done because of some limitation to the system, that you can't store those characters in the database, it will mess up their admin area, or the website doesn't support multibyte characters, etc. Which means either you're not sanitizing your inputs properly, aren't using prepared statemens and probably don't hash your passwords. Alarm bells should be ringing.
If I want to use a percentage sign or a Japanese character in my password, I should be able to do so. It will mean my password is harder for anyone else to guess. I cannot stand it when I come up with a really complex password like "l-.(mR{n<Pg1$Yh=u'C?^Wp_$ANNn'4gE+?@VE" and am told that my password can only contain letters and numbers. You're forcing me to choose a password that is much less secure than one I've chosen myself. That is unacceptable.
The Length Restriction
Your password cannot be longer than 16 chars.
Why not? The most common excuse for something like this, is that the database can only store 16 chars in the field, or that a designer only wants the input box to be a certain size.
Well, the designers argument is nonsense, since they can size the box however they want without restricting the amount of information that can be input. The database excuse is also nonsense, since you should be hashing passwords, so that they'll always be the same length after hashing anyway. So the password itself can be any length you want, yet you only have to store the 40 character hash output (or however many characters you force the hash to be).
A limit can be enforced, but it should be at least 100 characters at the minimum.
If I want to type a novel as my password, then that should be my choice. Restricting password length just restricts the search space an attacker needs to use and infuriates users who actually pick long complicated passwords by making them pick something less secure.
So what are the lessons?
Enforce some complexity if you have to, but don't restrict complexity. I should make it clear that I'm not against all password restrictions. It can depend on the environment. If you're storing the password for a system which has personal data, then enforcing a certain amount of complexity in the password is probably a good idea. I guess the point I'm trying to make though, is that it's easy to go too far. There's a point when it just becomes a hinderance to users, and ends up creating patterns which make the system less secure.
Try not to restrict user password choice. By heavily restricting what a user can enter as a password you're simply annoying your users and making it easier for an attacker to guess or brute force the password. By enforcing too many password restrictions you are making the system more predictable, and when it comes to passwords (and cryptography in general), predictability is a very bad thing.
It comes down to some very simple points.
- Don't resitrct what can go into a password, whether it's a max length or strange characters.
- Don't force a users password to follow a certain pattern.
- Don't force a user to change their password every x days unless you really have to.
- Store your passwords securely (strengthened, salted hashes).
If you follow these simple rules, your users will be happier, your database will always store the same length of data no matter what the user enters and you can be safe in the knowledge that you're not giving away any information to make it easier for an attacker.
Update (December, 2009): The best method I've seen recently is simply a blacklist of common passwords and dictionary words (this is the method Twitter use apparently). Users can pick a password of any length, with any characters they want and don't have to change it at any interval. They just can't use a common password or dictionary word found in the blacklist. Simple, effective and only reduces the search space by the common dictionary words which would've been easy to crack using brute force anyway.