Most of us, while developing sites swear to the rule of making error messages shown to the end-user as specific as possible, which goes a long way in creating a friendly UX. But the same rule if used in the login flow, can have significant privacy and security implications. On entering wrong login credentials, most sites show variations of
Invalid username/password error at the login screen.
It can be safely assumed that no user for such emails exists, yet the error messages shown by these prominent sites don’t indicate that. Do you see why?
On feeding random emails, a simple login/reset password may show that the user doesn’t exist and therefore no login/reset password is possible. A hostile client may create a list of valid users from this information. Not every site cares about it though. Facebook doesn’t.
It doesn’t hurt for a site like Facebook to leak the user base because everyone’s on it, but when the site is something like Ashley Maddison it can have implications.
People often argue that the user base is anyways leaked during the registration process, which can’t continue if the user already exists. This leak is avoidable too, by continuing the registration through an email. If the user already exists the email may say so, otherwise it may direct the receiver to continue the registration process.
In a brute-force attack, large number of combinations of usernames and passwords are tried to get into a user’s account. A dictionary attack is faster and better as it takes advantage of human tendencies of using common passwords and re-using old passwords. Specific messages like
Invalid username make these attacks faster by eliminating large number of combinations in a few tries.
To quantify the difference detailed error messages can make to brute-force or dictionary attacks, I created a script, login-attack-demo which included:
A collection of 1575 most commonly used passwords based on danielmiessler/SecLists.
A server which gives out specific error messages based on the failing stage of the login process. If the username is invalid, it’d say
A server which gives out vague error messages on failure of the login process. If the password is invalid and not the username, it’d still say
A hostile client which uses the dictionary to generate a pair of username and password and uses them to break into the system. It also analyzes the error messages on the following rules:
- An error message saying the password was invalid, indicates the username was a valid one.
- An error message saying the username was invalid, indicates no combination of password will result in a successful login.
- An inconclusive error message is ignored and the next combination is tried.
The blue points indicate the number of tries it took the attacker to break into the user’s account with vague error messages, while the red ones are when the error messages were specific. The yellow line is the max number of combinations to try.
It is evident that in theory vague error messages make it quite tough for the attacker, sometimes as much as 1000 times tougher. However, plugging all the holes may make the UX far from ideal. In the end, it all comes to trade off between UX and security. Depending on the space you’re operating, such methods can be used to safeguard the users.