34

Let's say that I have a system where one of the security requirements is preventing users from choosing a password that matches their username. Usernames are not case sensitive but the passwords are. The passwords are stored by the server using a secure hashing function that cannot be reversed.

When the account is created both the username and password are initially available in plaintext to the server for comparison. We can compare them in memory (while disregarding case) to see if they match and instruct the user to choose a different password if they do. Once this check is satisfied the password is securely hashed for storage while the username is stored in plaintext. No problems meeting the requirement here.

When the user wants to change their password, or it is being changed for them, the server can retrieve their username record and compare it to the newly chosen password value (again ignoring case) to see if it matches. No problems meeting the requirement here either.

However, the system also allows username changes. During this ID change process the user hasn't necessarily provided their password in plaintext to the server. They may have done so when they authenticated, but the server isn't going to keep that password stored in plaintext just in case they decide to change their username. So the plaintext password is not available to check for a match against the newly chosen username value.

In an attempt to meet our requirement the server can use the same secure hashing function to hash the new username and compare it to the recorded hashed password. If they match then the server can instruct the user to choose a different username. However, since the username is not case sensitive this check might fail when it is arguably true. If I submit "PwdRsch1" as a new username choice and my password is "pwdrsch1" then the system will allow it since the hashes won't match. I -- or worse, an attacker -- could then later successfully authenticate with a matching username and password of "pwdrsch1".

We could force the username to lowercase before hashing and checking it against the password, but then the reverse scenario is possible. The username would be checked as "pwdrsch1" against a password of "PwdRsch1" and allowed since these don't match. But later I can successfully authenticate with a matching username and password of "PwdRsch1".

What reasonable options do I have to reduce this risk of a password matching a username that is not case sensitive?

11
  • 3
    Depending on the hash, brute force might be feasible: given a username with N letters (excluding numbers), the search space is only 2^N. Mar 7, 2016 at 19:59
  • 8
    Allowing users to change their username clearly creates problems for your password management, and with most of the systems I work would cause other complications. Is it really all that important? IME the best security comes from simplicity.
    – symcbean
    Mar 7, 2016 at 19:59
  • 50
    When the username is changed, force a reset of the password.
    – user19474
    Mar 7, 2016 at 22:49
  • 10
    Why don't you just display some text in red that says "If your password is based on your username, there's a good chance somebody may guess it and steal your information."? I suspect this will take care of nearly every case. Programmatically enforced password complexity without attempts to educate users is this weird, ongoing nonproductive tradition. It's one of many reasons why nobody understands basic techniques for keeping their data safe, and why all these requirements and checks exist in the first place.
    – Jason C
    Mar 7, 2016 at 23:55
  • 2
    @DeerHunter: that's true but if anything makes it harder. If the account has a separate display and login name, and you're implementing this kind of measure at all, then you'd want to ensure that the password doesn't match either of them. So even if the login name cannot change, the fact that the display name can change means we still have this problem to solve (or fail/refuse to solve, as the case may be). Mar 8, 2016 at 11:44

8 Answers 8

107

The only sensible way to get what you want is to ask for the password when a user changes their username. This way the server always has the information needed to conduct an accurate comparison between the username and password during a change, and prevent matches.

As sensitive operations - such as changing passwords, or in your case usernames - should require a password anyways (to limit the damage of XSS), this shouldn't be a problem.

Your only other alternative is to try every possible case combination, hash it, and compare that to the stored hash when a user changes their username.

17
  • 1
    I agree that prompting for the password seems to be the most sensible solution when faced with user managed username changes. However, some systems (e.g. Microsoft Active Directory) allow administrators to change usernames without user involvement. In these situations the requirement for a user to provide their password isn't really compatible. I suspect your other suggestion of hashing all variations may be the only workable option of meeting the requirement. Otherwise we may have to be willing to allow for the risk of an admin-changed username matching a password.
    – PwdRsch
    Mar 7, 2016 at 19:53
  • 12
    @PwdRsch why would an administrator want to change usernames without user involvement? I can not imagine a legit use case.
    – emory
    Mar 7, 2016 at 19:56
  • 8
    @PwdRsch - Perhaps you can do the uname/password check on every login? Or on the first login after a username change? That said, how about you just fail to meet the requirements in those edge cases? They hardly seem worth worrying about. Mar 7, 2016 at 20:03
  • 4
    @emory brings up a good point. If the admin changes the username, what do you do if your policy is violated? Just not change the name? Use a different - incorrect - name? That doesn't make sense. (when the user changes it themselves, you could require a password change, but letting the admin change the password doesn't seem desirable; if it were, you could just make a password change mandatory and not have a problem)
    – tim
    Mar 7, 2016 at 20:11
  • 3
    If the admin changes the username, you could set a flag that the password needs to be changed. A link is sent to the user, notifying the change. The very next time that user logins, the password has to be changed. In my case, I always try to force the use of paraphrases which are way longer than usernames. Even better, ditch the password and use keys instead.
    – lepe
    Mar 8, 2016 at 1:26
13

Going against the grain a little - don't care whether the username is changed to a "substantially similar" string as the password. Warn users about the danger of selecting the same password and check for the identical match.

No matter how many rules you put in place, if the user is determined they'll find a way around them. If you must, prompt for the password upon username change so you can force them to the same casing, or just let it through and check the next time they log in and force a user/pass change then.

The only time any of this matters is if your users are subjected to a targeted attack. If a random script kiddie (or some other opportunist) gets ahold of the user list, they have way more sophisticated tools to break those passwords than trying to match the username. So does the targeted attacker, for that matter, but they may start with simple things they can type into the keyboard themselves. And if it's an intelligent person trying to break the password "PwdRsch1", are you really going to be safe just checking case differences? What about "pwdr5ch1"? "PwdRsch2"? "1hcsRdwP"? You can write rules for any of these scenarios you can think of, but either there'll be one you forgot or you'll make it so difficult to select a username/password combo that they'll just wind up using "P4ssw0rd!" and be done with it.

Education is the only way to get your users to use genuinely secure passwords, and there will always be those that don't comply.

2
  • I do agree that a determined user can choose a weaker password than we might like, despite the policy rules or other controls we use to prevent bad choices. However, I don't feel like this requirement (as stated) is taking things too far. Pair that technical control with education as you suggest and hopefully we gain the security advantages of both. However, just because most attackers will make guesses beyond a password matching the username doesn't mean that we shouldn't attempt to enforce this rule. We still need to eliminate the low hanging fruit.
    – PwdRsch
    Mar 8, 2016 at 16:55
  • @PwdRsch I don't disagree, my point, I suppose, is that you don't need to hide what you're doing from the user - explicitly requiring them to enter their password when making a name change, or running the same check the next time they log in after an admin changed their name, actually improves the education because it gives them a reason to pay attention. That said, if an admin is able to, essentially, accidentally guess a user's password when selecting their username, then that's a reason to offload the education onto the user anyway because that was a horribly chosen password.
    – Jason
    Mar 8, 2016 at 20:59
8

Let's say the username has 10 letters in it. That's 1024 different combinations of upper and lower case. Check them all.

Don't store the lower case password hash. That 1024 may seem inconvenient to you, but it's the difference between a day and three years for a attacker.

4
  • 5
    Depending on the hashing and the hardware, it may take around a minute for that. If an admin changes the username that might be fine (if it is clearly displayed that this is a slow process), if a user changes it, a minute might not be acceptable. It may result in problems, eg users resubmitting forms and then not knowing with what username they ended up with, or users closing the window before they get the message that their new username is not acceptable.
    – tim
    Mar 8, 2016 at 14:32
  • @tim It needs to be slow. Otherwise, an attacker who takes over the server or has a replica of the server could simply keep trying to change the username until they figure out the password (in practice they could make something much better than the server). You can trade speed for space though: en.wikipedia.org/wiki/Scrypt Mar 8, 2016 at 17:00
  • 1
    If you (assumed to be a non-expert password cracker) can brute force it, an attacker can do the same much, much quicker. If you are an expert password cracker, then you already know the futility of what you're doing.
    – Jason
    Mar 8, 2016 at 21:00
  • @Jason you don't need to know the password, just make sure that the username isn't the password. Mar 8, 2016 at 21:01
4

You should force userids and passwords to come from different sets. In the comments it appears that the userid must follow from the user's legal name in a formulaic way "John Smith" -> "jsmith" and "Jane Doe" -> "jdoe". Then if Jane marries John and takes his name, then her user id must change to something like "jsmith2"

So you could stipulate that the first character in a password must be a symbol or that the password must contain a symbol.

If userids are truncated at 8 characters you could require that passwords must contain at least 9 characters.

You could take the cartesian product of a list surnames and a list of given names and use that as a blacklist for passwords. If a employee has a name that was not on your list, add it, and as people change passwords the problem will fix itself.

5
  • 8
    Brenda Utthead would have a colorable objection to your proposed policy, especially if usernames are used in public communication. Mar 8, 2016 at 5:11
  • @DamianYerrick To be clear it is my understanding that the OP has a strict requirement that userids be derived formulaicly from legal names and not match passwords. I think users should be able to pick their own userid which need not resemble their legal name. Brenda's objection has more to do with OP's requirements than my policy.
    – emory
    Mar 8, 2016 at 8:44
  • @DamianYerrick in comments, the OP said that if Brenda Smith (userid bsmith, password butthead) married Rick Utthead (userid rutthead) and took Utthead's name, then the admin would have to change Brenda's userid to butthead but that would be a problem because now her userid and password are the same.
    – emory
    Mar 8, 2016 at 10:33
  • @DamianYerrick but if you believe that the userid matching the password is not the big problem in Brenda's scenario, then I have to agree.
    – emory
    Mar 8, 2016 at 10:36
  • 1
    @DamianYerrick Cisco Systems actually did that, and seemed spectacularly unlucky with their staff names, along the lines of Chris Rapherty, Simon Hitchin, and so forth. I believe they also truncated their usernames to 8 letters. Much amusement (outside Cisco) ensued.
    – abligh
    Mar 9, 2016 at 8:25
2

This is not an answer, I'm only mentioning it so that people don't do this.

You might decide that it would make sense to store, in addition to the regular hash of their case-sensitive password, a hash of their password converted to all-lowercase.

This would certainly solve your problem - you just lowercase the username that you're changing to, and compare it to this stored hash of the lowercased password.

The obvious downside is that this partly defeats the purpose of a hashed password in the first place: to make attacks on your password list much harder. An attacker gaining access to your hashed password lists would be able to attack the far weaker (2^n times weaker) lower-case hash instead of the case sensitive hash.

So the other options mentioned (asking for the password at time of change; trying all case permutations if an admin changes it, ideally in most-likely order first) seem far better bets.

4
  • 1
    This was one of the early answers offered as a seemingly good option that the poster then later deleted once people chimed in with the warnings you list. ;) I agree that the tradeoffs in security don't really make this worthwhile.
    – PwdRsch
    Mar 8, 2016 at 17:22
  • @PwdRsch Oh, thanks - I didn't realize. This answer, for once, I'd be perfectly fine to see getting uncommented downvotes :) Mar 8, 2016 at 18:11
  • 2
    @DewiMorgan You could make it CW... that way you wouldn't lose rep for the downvotes.
    – wizzwizz4
    Mar 8, 2016 at 18:16
  • Ooh, thanks, @wizzwizz4, I didn't know that. Done! Feels kinda... naughty and exploitatious, though :( Mar 8, 2016 at 18:27
2

Some great answers already, but here is an alternative way to approach this issue. Instead of trying to compare the new username to the existing password, you could simply force a password change anytime a user changes their username.

Naturally, you would want to warn users that changing the username will require changing the password, but you can then easily use whatever process already exists to check new passwords against usernames.

0

While the most sensible solution has been already mentioned and accepted, namely asking for the password on user name change because you should be doing that anyway. An alternative is to also store the hash of the lowercase password (with a different salt?) and comparing the all lower case username to that.

0

The only way to prevent users from picking dumb passwords is by forcing password generation policies (as opposed to the woefully common password format policies).

Now, if you don't have that much authority over your users (most websites don't), you should at least tell them to generate their passwords with a password manager (and generate their master password with dice), and you might be able to make it difficult to disobey this policy:

One way you might do this is by making your password field not accept keyboard input, but instead only pasted data or machine-typed data (I recommend checking the speed at which characters are entered). Then you can have the box explaining the password policy be outlined in red or something to draw their attention back to it.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .