Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

/////////////////////////////// Updated Post Below ////////////////////////////

This question has received a lot of hits, more than I ever thought it would have on such a basic topic. So, I thought I would update people on what I am doing. Also I keep reading in the comments that I am storing passwords as plain text. Just to clarify I am not.

My updated validation function :

public function is_password($str) {
        if (strlen($str) < 10) { // Less then 10
            $this -> set_message('is_password', 'Password must include at least one number, one letter, one capital letter , one symbol and be between 10 and 100 characters long.');
            return FALSE;
        } elseif (strlen($str) > 100) { // Greater then 100
            $this -> set_message('is_password', 'Password must include at least one number, one letter, one capital letter , one symbol and be between 10 and 100 characters long.');
            return FALSE;
        } elseif (!preg_match("#[0-9]+#", $str)) { // At least 1 number
            $this -> set_message('is_password', 'Password must include at least one number, one letter, one capital letter , one symbol and be between 10 and 100 characters long.');
            return FALSE;
        } elseif (!preg_match("#[a-z]+#", $str)) { // At least 1 letter
            $this -> set_message('is_password', 'Password must include at least one number, one letter, one capital letter , one symbol and be between 10 and 100 characters long.');
            return FALSE;
        } elseif (!preg_match("#[A-Z]+#", $str)) { // At least 1 capital
            $this -> set_message('is_password', 'Password must include at least one number, one letter, one capital letter , one symbol and be between 10 and 100 characters long.');
            return FALSE;
        } elseif (!preg_match("#\W+#", $str)) { // At least 1 symbol
            $this -> set_message('is_password', 'Password must include at least one number, one letter, one capital letter , one symbol and be between 10 and 100 characters long.');
            return FALSE;
        } else {
            return TRUE; // No errors
        }     
    }

Each time it returns FALSE, I always tell them the entire password need.

Just to answer some of the questions as to why it is so long :

Why not so long? People at my job that I talk to use sentences. Very long ones at that.

How am I hashing my passwords? / Why use 100 characters? -> just use better hashing algorithm

For PHP, I am using the best there is for this language. I am using this library which is the PHP 5.5 equivalence of the new password hashing API created by Anthony Ferrara. My reasoning for this hashing use is simple, very high demand on the CPU (if you ever test it out on a Linux/Windows box CPU usage is at 100%). Also, the algorithm is very scalable due to the cost factor the higher the cost the more grueling the task is for the CPU to log a person in. Last I "Tested", I put the cost to 24. An entire hour passed for me to try and login and I got a PHP time out error before I even got past the login screen (this was a foolish cost factor). A study done by Jeremi Gosney (THIS IS THE PDF DOWNLOAD OF THE REPORT) which tested the strength of this function compared to other more popular ones (yes, more popular) concluded that even with 25 - GPUs, while using bcrypt at a cost of 5, password hashing is the last of your concerns. I use a cost of 17...

My function if any one is interested (The parts that pertain to this subject at least) :

public function create_user($value) {
        $this -> CI = get_instance();
        $this -> CI -> load -> library('bcrypt');

        foreach ($value as $k => $v) {// add PDO place holder to the keys
            $vals[":$k"] = $v;
        }
        $vals[":password"] = $this -> CI -> bcrypt -> password_hash($vals[":password"], PASSWORD_BCRYPT, array("cost" => 17)); // Take old $vals[":password"] and run it through bcrypt to come up with the new $vals[":password"] 

Hopefully this question helps others out there.

/////////////////////////////// Original Post Below ////////////////////////////

I'm currently working on a new project, and an issue struck me.

Is it it safe to disclose your password requirements? If so, why is it safe?

I have a function that does validation on a password and each step shows the user why validation does not work.

Here is my function:

public function is_password($str) {
    if (strlen($str) < 10) {
        $this -> set_message('is_password', 'Password too short.');
        return FALSE;
    } elseif (strlen($str) > 100) {
        $this -> set_message('is_password', 'Password is too long.');
        return FALSE;
    } elseif (!preg_match("#[0-9]+#", $str)) {
        $this -> set_message('is_password', 'Password must include at least one number.');
        return FALSE;
    } elseif (!preg_match("#[a-z]+#", $str)) {
        $this -> set_message('is_password', 'Password must contain at least one letter.');
        return FALSE;
    } elseif (!preg_match("#[A-Z]+#", $str)) {
        $this -> set_message('is_password', 'Password must contain at least one capital letter.');
        return FALSE;
    } elseif (!preg_match("#\W+#", $pwd)) {
        $this -> set_message('is_password', 'Password must include at least one symbol.');
        return FALSE;
    } else {
        return TRUE;
    }
}

My thought on this is, if we let the "user" / attacker know what my passwords consist of wouldn't it be easier for the attacker to know? I know security through obscurity is not a best practice, but could it be a strong argument in this situation?

I would like to know if I am going about this in the right way. Any help would be great.

share|improve this question
25  
Personally I don't like having such rules at all. I'd rather estimate the password complexity. Even dumb estimates are better than such annoying rules. –  CodesInChaos Aug 13 '13 at 18:33
72  
You might want to revise your checking for a better experience. Lets say I enter a password woot. That will fail because its too short. Then I do wootwootwoot. Now it fails because it has no numbers. Then w00twootwoot, fails no capital. Then W00twootwoot, fails no symbol. At which point unless I have to log into your application to do my job I'm going to throw a fit and go do something else. Revise your checking to tell me all of the password requirements up front and make the validation tell me all of the missing requirements if I don't hit them. –  Freiheit Aug 13 '13 at 21:33
1  
You know @Freiheit I was actually thinking that, what if my users go down the list (for the 6 checks). I am actually doing that right now. I would be utterly pissed off especially in my register form, because I also have security question, and the answes to those questions reset if goof up happens :P –  Rixhers Ajazi Aug 13 '13 at 21:36
22  
Out of curiosity, why a "Too long" constraint? My limited understanding says that once you hash the password, it should be irrelevant –  Akash Aug 14 '13 at 5:01
1  
@Quillion The fact that is somehow an XY problem (asking about showing password restrictions asserting such restrictions were actually a incontestably good idea; and fortunately most answers here address that issue as well) is not a reason for closing the question - on the contrary, anyone else asking this should find the answers here pretty enlightening. You may however downvote the question at will since you obviously deem it "not useful" –  Tobias Kienzler Aug 16 '13 at 10:17
show 1 more comment

4 Answers

up vote 85 down vote accepted

If you do not divulge your "password requirements" then your users will hate you. Some will not succeed in finding an "acceptable password" and will call the helpdesk. Or, worse, if the users are customers then they will go buy elsewhere. A great way to kill your own business !

On the other hand, if divulging your "password requirements" really help attackers in a non-negligible way, then your password requirements are awfully bad: not only do they antagonize users, but they also restrain the users into a too small set of possible passwords.

Note that attackers can usually guess quite well what your "password requirements" are, e.g. by trying to register themselves.

In any case, "password requirements" are counter-productive and decrease security, save for a "minimum length" which can be rationally justified. So just don't do that. Key to password security is user education, possibly helped with some tools (e.g. a random generator for strong passwords). Enforcing constraints does not help; and enforcing hidden constraints is just worse. For instance, if your rules call for at least one digit and one symbol, then a surprisingly high proportion of users will just append "1." at the end of their password; attackers know that. The extra suffix will not add much to the password entropy (i.e. the number of potential passwords the attacker has to try for a successful break) but will use up some of the scarce resource known as "user patience": users will prefer shorter passwords, since they have to add the "1." suffix to appease your server.

share|improve this answer
2  
Very good answer, and yes your absolutely right, they will hate me... even more then they hate me atm :P Alright, you answered my main question : The attacker can try to register them selves and find what my PW requirements are exactly. –  Rixhers Ajazi Aug 13 '13 at 21:23
    
@Tom Leek - do you have any suggestions on how to combine a random generator with a signup form? I'm thinking Google's app-specific authentication would be similar but perhaps you had another idea... –  Jedidja Aug 14 '13 at 0:02
10  
Just wanted to support the claim of user hate. Where I work the password requirements are hidden, and it generally takes me at least 5-10 minutes to create a password the system will actually let me use. If the requirements are hidden failed attempts will quickly lead to user rage. –  Daniel Cook Aug 14 '13 at 1:29
1  
@Jedidja: for a password generator, provide it as a button on the same page as the login form. If the button is pressed, then a new random password is generated and displayed. Don't autofill the password entry field, though: the user still has to remember the password, and making him enter it twice is a good start for that (so you should display it as a picture, not as text which can be copied & pasted with a mouse). –  Tom Leek Aug 14 '13 at 10:41
3  
@DanNeely: that's why I advocate for a non-mandatory password generator. It is important that it is optional; it must not be forced unto users, otherwise they will rebel, and that's the last thing we want. The password generator is a helpful tool which complements the normal process of "users thinks of the new password by himself". –  Tom Leek Aug 14 '13 at 15:13
show 4 more comments

If you don't tell the user exactly what's needed in his password to go through the validation of your function, how would he know what to add or modify to make it valid?

Giving such information could result in making a bruteforce attack easier. However, considering your requirements, it doesn't help the attacker at all because there are too many password possibilities to make an attack worthwhile.

share|improve this answer
    
Thanks for the great answer! –  Rixhers Ajazi Aug 13 '13 at 21:30
    
Just note that it'd be better to simply not enforce such requirements, since it encourages users to write down their overcomplicated password close to their PC. Or they'll simply equal "forgot password == login button" –  Tobias Kienzler Aug 16 '13 at 10:13
    
@TobiasKienzler I most certainty hope that doesn't happen. None the less if they need to use forgot password I shall be just fine to. I love your input to this question! –  Rixhers Ajazi Aug 16 '13 at 13:07
    
@RixhersAjazi You're welcome, thanks for the added info. Good thing you decided to show the info now at least after the first attempt, that's something I could bear with if the service was interesting enough ;) And good to hear you use bcrypt - but why limit the password to 100 characters? It's sure enough a more sensible limit than, say, 20, though... Nonetheless please reconsider Tom Leek's comment about users rebelling if you enforce this –  Tobias Kienzler Aug 16 '13 at 18:24
    
@TobiasKienzler I sort of can't not enforce this =\ I completely agree with you all on this is pretty crazy, but on the other hand, my IT department at the school I attend (I'm still a student I don't even work for the IT department) will have "hissy-fits". For this program to ever be used I got to sell it to the IT department. Hell if you think this password requirements are crazy you should have a look at my security questions :P Its just the line of work I am in. This application is going to hold a lot of important information on students (my information included). –  Rixhers Ajazi Aug 16 '13 at 22:29
show 4 more comments

Users/customers will most likely restrain from using your service once their third attempt at entering a valid password failed. Hackers in contrast will try to register arbitrarily often to figure out your password requirements as precise as possible.

To counter this, validate the user first via the usual means (email, captcha etc) and send them a password token. This already reduces the amount of fake valid users, and by blocking too many password changes in a specific time you make hackers' life harder. However you should still disclose all password requirements no later than after the first attempt of entering an invalid one.

But better yet, I recommend not forcing users to choose an arbitrarily complex password that they will simply end up writing down on a post-it next to their monitor (or having them reset their password as simplified "login"). Instead, let them know that their password is weak, tell them what a good yet memorable password is (e.g. use a pass- phrase instead) and allow them to proceed anyway after clicking a "Yeah, I understood my password is not very secure, let me proceed anyway" - it's their fault if the account gets hacked then and you should not be liable after this explicit warning. Assuming you did use a proper and established password hashing instead of homebrew-crap or, worse, plaintext.

share|improve this answer
3  
Also - the 20 character lower case password is more secure (~94b) then 8 character password having lower and upper case letters, symbols and numbers (~52b) if both are perfectly random - yet the former will not be allowed while latter will be. –  Maciej Piechotka Aug 14 '13 at 10:21
2  
Precisely. Ultimately all enforced password constraints yield failure, it should be up to the user to wager whether the respective access shouldn't be secured via e.g. a KeePass generated password in that case... –  Tobias Kienzler Aug 14 '13 at 10:24
add comment

Think about the scenario -- how does the attacker get the requirements? Most likely because they can register themselves. In which case it is trivial to reverse engineer your requirements unless they are too complex to use without an explanation. So, yes, it's safe to let the user know what your requirements are.

But a better approach is to not require a password at all, OpenID if at all possible. It's almost certainly going to be at least as secure as whatever you use for gathering and storing passwords. And for anyone with a gmail or yahoo account, it's definitely going to be easier.

share|improve this answer
1  
Though using OpenID means you're relying on an external service. Which might (depending on requirements) work for a web-based application that users interact with, but won't work as well for a web service (computer-to-computer communications), or for a locally installed application that must be able to run without network access, or if the OpenID service is ever unavailable for any other reason. –  Michael Kjörling Aug 15 '13 at 9:20
1  
@MichaelKjörling: For computer-to-computer interaction something like OAuth token is probably a better way then password. –  Maciej Piechotka Aug 15 '13 at 14:14
    
@MaciejPiechotka Possibly, but the answer talked specifically about using "OpenID if at all possible". –  Michael Kjörling Aug 15 '13 at 14:17
add comment

protected by Adnan Aug 14 '13 at 18:33

Thank you for your interest in this question. Because it has attracted low-quality answers, posting an answer now requires 10 reputation on this site.

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.