72

Occasionally (though rarely), some of our users say that their password doesn't work: they say that they have typed the correct password but got the 'wrong password' message.

We tell them to use the reset password feature, which they do, but they stay with that feeling that the authentication system sometimes doesn't work.

Our guess is that their password is not what they remember, but since we don't store it in plain text, do we have any way to prove that's the case?

On some occasions we were able to show them that on a certain date they had changed their password and then forgot about it, and they were satisfied. But that's not always the case.

psmears
  • 900
  • 7
  • 9
Mario Trucco
  • 1,559
  • 2
  • 11
  • 25
  • Comments are not for extended discussion; this conversation has been [moved to chat](http://chat.stackexchange.com/rooms/48508/discussion-on-question-by-mario-trucco-how-to-prove-that-authentication-system-w). – Rory Alsop Nov 14 '16 at 20:00

9 Answers9

85

There's not a really quick way to prove this because the hash is designed not to be reversible.

You could take their claimed password, and manually generate the hash as @TechTreeDev suggested. You should be using a salted hash (i.e. BCrypt) so make sure you use the same salt.

  • If the manually generated hash matches, then you've proved an issue in the login code.

  • More likely the generated hash will be different, then you've ruled out login code issues, but there still could be an issue with the password setup, or a mistake in your manual generation.

That's pretty much the extent of what you can do to check a single person's password. Beyond that we get into system testing.

  • If you suspect an intermittent/random chance edge case, you could create a monkey test script to set up passwords and then try them. This approach is probably overkill though.

  • The best thing is to review your login code and all points that reset the password. The code should be as short and concise as possible. In my experience, the best way to rule out edge case issues is with code review, as such edge cases are often not covered by manual testing.

A few things to specifically look for:

  • Make sure that maxlength setting is consistent (or better yet, not present) on any password <input>s. You are looking for consistency between password set up and the login form.

  • Make sure there is no server-side truncation.

  • Make sure that encoding is consistent. If a non-ASCII character is used in the password, the password setup form and login forms need to behave exactly the same.

  • Also don't automatically strip anything like whitespace or non-ASCII characters from the password. This is the kind of thing you can easily catch with a code review if your code is concise.

Finally some human tips:

  • Verify they are using the correct username first.

  • Check the caps lock setting is correct.

  • Give the customer support folks a log of every date/time of login or of password reset. If there has been at least one login since the last reset then they know the system worked correctly.

    As long as the login code is unchanged, and the hash is unchanged since last success, then you can be reasonably certain that the issue must be a mis-typed password.

  • Review the UX of the Wrong Password error, providing the user with some simple tips and authoritative explanation of possibilities. This may reduce call-ins to customer service.

  • It may be helpful to email notify the customer when a password is reset to remind them. (or other family member in case of shared accounts)

700 Software
  • 13,897
  • 3
  • 53
  • 82
  • 8
    Along with the encoding step, I'd also check that any data validation or character filtering performed is also consistent. LinkedIn once allowed me to put the | character in a password and log into their web site perfectly fine. But their mobile app apparently didn't accept passwords with that character and refused to authenticate me until I removed it. – PwdRsch Nov 09 '16 at 17:28
  • 2
    The first two human tips are important and hand in hand. It is not an uncommon practice to trim and convert the user supplied username and the DB username to all one case so they match correctly. This is especially useful for when cell phones want to auto cap the first character. We can seem to convey to everyone case sensitivity with passwords but unfortunately that isn't the case with usernames. This is one of the times you may have to sacrifice security for usability. – Bacon Brad Nov 09 '16 at 18:03
  • 20
    Additional human tip: Verify they are using the same **input language** and **keyboard layout** as when they created the password. If they have multiple languages installed on their PC, they might have accidentally hit the key combination that toggles to the next language, so the keys they are pressing are not producing the characters they expect. – shoover Nov 09 '16 at 18:16
  • In terminal server connections the problem is sometimes that if there is not a sufficiently long delay between pressing the shift key and the letter key for the uppercase letter you want to type then the shift signal comes to late to the server and the password field gets the lowercase letter as input. That gave me many times the feeling of being completely stupid and not remembering my password. However, this is limited to mstsc, I have never had that problem with web logons. – kaidentity Nov 09 '16 at 18:49
  • I've had a similar experience where the shift key would not release quickly/strongly enough on a lesser quality laptop keyboard, causing me to capitalize an additional letter by accident. Sounds like your terminal experience delay was more significant though. – 700 Software Nov 09 '16 at 18:55
  • I'm not sure code review is the right way to catch your password handling stripping characters, because this should be automated. Include passwords that test all contingencies in your integration test suite, and make sure the hashes stored in the database always match the passwords that were entered. – Mike Scott Nov 10 '16 at 10:42
  • 4
    I agree that one shouldn't strip whitespace *within* a password but a case could be made for at least *trimming* whitespace. An accidental space at the start or end is quite common. I know of some people who instinctively add a space at the end of every input (I guess because they're so used to adding a space after words). – Michael Nov 10 '16 at 11:50
  • 49
    Whatever you do: **Don't train users to give anyone their password** – Dennis Jaheruddin Nov 10 '16 at 12:18
  • 3
    Leading spaces has been a big issue among users for me too. People are so used to hitting spacebar to bring back computers from sleep that they do it at login screens instinctively... – Brian Knoblauch Nov 10 '16 at 14:23
  • 1
    I think we all agree not to strip internal whitespace. Personally, I don't think it's appropriate to remove leading or trailing whitespace either. (Computers should be predictable IMHO) That being said, it looks like Google does this. – 700 Software Nov 10 '16 at 14:33
  • Another item: make sure the hashing is always done by the target DBMS or LDAP server, not by your own code. That way you're far less likely to introduce a hashing bug, and your own code becomes a lot more transparent, e.g. `SELECT COUNT(*) FROM USERS WHERE USERNAME=? AND PASSWORD=H(?)` for some hash function `H`, where the result is 1 on success and 0 on failure, and similarly `INSERT INTO USERS (USERNAME,PASSWORD) VALUES (?, H(?))` for the same `H`. – user207421 Nov 11 '16 at 00:48
  • 1
    @EJP, That's not a good idea because passwords can be exposed via statement log, binlog or `show processlist`. Also, it's more important to choose the correct hash algorithm (i.e. BCrypt, scrypt, Argon2) and some database servers (i.e. MySQL) do not offer these choices internally. – 700 Software Nov 11 '16 at 01:28
  • Logging password changes. You can say, you changed your passsword on ... and last logged in ... and failed to log in ... – Ramhound Nov 11 '16 at 03:41
  • "Don't automatically strip" applies to the username as well. But so does "don't stop automatically stripping" which has caused me trouble before (as a user) – Chris H Nov 11 '16 at 16:30
  • For debug purposes I would make the password change logging store the hash to the log (not displayed to the user.) This lets you quickly verify that there has been no inadvertent password change since. – Loren Pechtel Nov 14 '16 at 07:00
  • @BrianKnoblauch I have noticed that some people also use Spacebar instead of Backspace, especially older generation and non-tech savvy people. – ROAL Nov 14 '16 at 09:02
  • 1
    Having different hashes doesn't prove much - you can have an issue on your hash-generating code. – T. Sar Nov 14 '16 at 10:29
25

There's one way to know for sure, and that is calculating the hash of what the user entered, using the same salt, and comparing that with what you have. However, that's what the login process already does and the user doesn't believe that. Why should they believe it when you do it for them?


Instead, you could do what I've been seeing a lot lately, in Windows 10 for example, but also on websites:

Give the user a way to verify what they've entered.

Of course, when logging in, the characters should be represented as dots or other characters, so snoopers can't see the password by looking over the user's shoulder.

But as long as it's in the input field, it hasn't been encrypted or hashed in any way yet. So provide a button that turns those dots into the actual characters.
That way, after entering the wrong password, they can enter it again and see what they've just entered. Or they can check prior to logging in.

Forgotten CapsLocks, hanging Shifts, typos; they can all be detected by the user this way.

SQB
  • 421
  • 3
  • 11
  • 2
    Yes, a great idea. Since most sites don't implement this (yet), and most of those never will implement it, I use the FIrefox Add-on: "Show my Password". – Kevin Fegan Nov 14 '16 at 14:53
6

To improve your user experience you need first of all add some UI to tell users of the following conditions:

  • Caps lock activated
  • Warning if there are trailing whitespaces in username
  • Warning if there re trailing whitespaces in password
  • prevent using whitespaces in email (if using email instead of username)
  • prevent using and automatically remove newlines (there are several new line variants)
  • prevent using and automatically remove control characters
  • if you are using Javascript, some browsers have it disabled, so you have to move these steps on server side.

Also when password inserted is wrong display the following message:

Password or username/mail is wrong, please type it paying attention to lower-case or uppercase letters and all symbols numbers, they must match perfectly. Avoid doing copy-paste because sometimes copying text may add additional unwanted whitespaces and/or newlines.

Keep in mind that your users may be right! I once had a old phone that didn't allowed me to login into a web page, I don't know if that was a text encoding issue but my password was alpha numeric and worked perfectly on a PC.

CoffeDeveloper
  • 516
  • 3
  • 12
  • 2
    This message implicitly discourages the use of password managers. I use the autofill option the most on my manager, but right after that usually comes the copy-paste option when autofill doesn't work because of flash/domain name/input field code/general incompatibility. – Nzall Nov 10 '16 at 23:06
  • It also contains a comma splice. – JDługosz Nov 11 '16 at 09:56
  • @Nzall He's not saying to technically prevent people from pasting. People who use password managers know what they're doing - people who copy and paste from a text file, email message, word document, are likely to introduce unwanted whitespace. – Random832 Nov 12 '16 at 11:37
3

The accepted answer really covers most of it. But assuming that I tried all the suggestions there and still couldn't find the problem, I'd then try to catch the error when it happens. To do that, you could add code that logged the received plaintext password if a user failed to log in twice in a row (so as to filter out all the users who just made a stupid error and corrected it on the second try).

In order to not weaken the security of your system, you could only enable the password logging when there actually was a user on the phone who had trouble logging in, and log only his/her password, with his/her consent.

Logging the actual password your application sees has the advantage that you see exactly what your application sees. After a few calls from desperate users, you might start to pick up a pattern in their passwords (e.g. trailing space, special characters etc) which pointed to a problem in your login code, or you might see that they meant to type "mysweetheart" but typed "myseetheart" instead, which would mean that the login problems were most likely all user error.

Out of Band
  • 9,200
  • 1
  • 22
  • 30
  • 3
    This sounds borderline sketchy. I would never ever trust a system once I knew an admin could see my plaintext password. – Pranab Nov 11 '16 at 10:24
  • 5
    I'd agree on principle, but the sad truth is that the admins of all the servers that serve your sign-in webpages most likely CAN see your password if they want to. So how do you know the services you are using every day don't do this? The only thing that keeps your password confidential is their morals and company regulations. – Out of Band Nov 11 '16 at 16:55
1

I don't think manually performing the password hashing steps would be the solution. Should you have detected that it indeed fails, sure, you may do that at low-level to debug, but your customers will forget about it almost immediately.

Here the problem is that they are using a wrong password, either because they mistyped it, or really think they had used a different one than the one they did.

To rule out the first case, make them write the intended password in a text editor (eg. notepad), cut it to the clipboard and paste into the password field. The password is showed to the customer during the process, so that removes the cases where a wrong letter is being pressed, Caps Lock was set… (of course we are expecting that they do this at a time when nobody else is looking at their screen)

The second case is harder, as we do not want to encourage the customers to keep a text file with their passwords. Ideally, you would convince your customers to use a password manager like KeePass. Then, if the password -the same that worked before- is correctly copied from the password manager, you can be quite certain that it is indeed the right password.

Other than that, which really requires a change of mind of your customers, you may ask your customers to:

  • create a new password
  • change their password to that by pasting it
  • try logging in with the same password they have in the clipboard

as many times as they want, in order to attempt to reproduce it.

Ángel
  • 18,188
  • 3
  • 26
  • 63
1

Assuming you are logging whenever a user logs in, you may be able to show that they have been able to log in since they last changed their password, That would at least be sufficient to rule out some potential issues.

Nick
  • 121
  • 1
1

On encountering four different authentication systems with this actual property, it's fairly easy to verify in each case.

Case #1: System randomly fails. On failure, the incorrect login counter is not incremented. (I haven't been able to inspect the insides but I'm pretty sure what's happening is it sometimes loses connection with another server and just reports incorrect password when this happens.)

Case #2: System blew up when I put an apostrophe in my password. Demonstrating the password field was subject to SQL injection was trivial.

Case #3: Valid password was rejected by a character filter on the login screen the password screen didn't have. This was trivial to demonstrate the problem as well.

Case #4: System would not let me log in becasue it interpreted at-sign as kill line. Booo. Logging in by telnetting to the FTP port proved I had the right password.

Joshua
  • 1,090
  • 7
  • 11
0

You could store each users last few (hashed) passwords in your database. If the entered password does not match the current password, compare it to the old one(s). If there is a match there, present a "You have entered an old password - try again" message, or error code to that effect (so when they contact you, you can ask "Do you see Error Code 47? That means you have used an old password.")

This way, you can be fairly sure the login system is working as it has made at least some password lookups and the user gets some feedback that they have forgotten their new password.

b04ty
  • 11
  • 1
    This would also introduce a user enumeration flaw, though - if a password DB is dumped, and the user changes their password following this, an attacker with the dump can still confirm that the user exists. If they just get the standard error, they can't tell once the password has been changed. It's a slim possibility, but still. – Matthew Nov 10 '16 at 15:48
  • 1
    This does sacrifice some security. There is a more detailed discussion here: [Does Facebook storing old passwords compromise security?](http://security.stackexchange.com/questions/137641/does-facebook-storing-old-passwords-compromise-security) – 700 Software Nov 11 '16 at 01:32
0

I'm posting a second answer which I thought of yesterday, but wasn't sure it was advisable.

You could create a temporary log of passwords set/reset and attempted in an encrypted form. Security experts (including me) would shudder at this idea of encrypting (instead of hashing) passwords (or even incorrect password attempts), so I would suggest three precautions if you decide you need to start logging this information.

  1. Submit the information to a separate/isolated computer so if the main server is compromised then the passwords log is still safe.
  2. Use public key (asymmetric) encryption for the logged information. The private (decryption) key is only stored in an isolated environment for the developer to review the logged data.
  3. Schedule a task (or code it in) so that this temporary log is disabled at a particular date, or when a sufficient number of tests have been successful.
700 Software
  • 13,897
  • 3
  • 53
  • 82
  • 2
    I am not sure that sacrificing everyone's security just to prove some stupid people wrong is a good idea. This is a huge risk, even if all precautions are taken. Also from the question it seems that customer service would need access to this info, so they may not be as trusted as developers. Finally testing the password system can (and should) be done with unit tests on a demo database. – André Borie Nov 10 '16 at 20:43
  • Following precautions 1 and 2 this may be an acceptable risk, so long as the term isolated is followed carefully. (i.e. computer with no direct internet access, and only a select few network services for a single developer to use) That could be a slippery slope of temptation though. Obviously making these available to customer service would be a huge risk! (i.e. that wouldn't be very well isolated) – 700 Software Nov 10 '16 at 21:07
  • 1
    If you're going to do something like this put a field in the file that says whether such logging should be used and only turn it on on the people that are complaining. – Loren Pechtel Nov 14 '16 at 07:04