Matt Basta

My Blog

Your Authentication Sucks

I had a conversation with my coworkers the other day about authentication and I was surprised at the amount of apathy that they showed over indications of bad authentication systems. Some of the systems discussed were login mechanisms for banks, credit card companies, and more.

I'm not one to rant (disclaimer: yes I am), but this is something I'm very passionate about. Not because I care that much, but because it shows that the corporations that are protecting our most valuable assets--money, identity, etc.--are less concerned with doing things the right way and more concerned with filling the potholes with quickpatch.

In today's world of infosec roulette, it's so much more pertinent that you take greater care of how you protect your assets online.

Signs of a busted-ass authentication system

Consumers: if you see any of these things, you should be suspicious of the service you're using. Be very sure that you use a unique password (more sure than usual), as these are often indications that the service is doing something very wrong and your password is more likely to get compromised than your average website.

Administrators: if you're doing anything on this list, please remediate your website immediately. You're putting your users and your investors at risk and what you are doing is bad.

Maximum password length

There's absolutely no reason that passwords should have a maximum length. At all. Ever. Of course, there might be a technical limitation of a kilobyte or two thanks to the server software you're running. If I, however, want to use a password that's 50 bytes long, I should be able to do it.

Why it's bad: Forcing users to fit their passwords within a certain length is directly forcing the user to limit the amount of entropy in their password (or in some cases, passphrase). Setting a hard cap means that if your database is breached, even properly hashed passwords are much easier to crack since there's a finite number of passwords that can be chosen.

What it indicates: More often than not, this limitation means that on the back-end, the passwords are being stored in plaintext or with two-way encryption in a fixed-size database column (e.g., VARCHAR). This is the worst possible way to store a password, since ANY data leakage from the table storing the passwords will result in all of your users' passwords being compromised.

How to fix it: Implement proper hashing and salting. This should be easy, unfortunately, since you have a copy of the passwords to hash and salt. Remove the limit.

Password character restrictions

Oh, I can't use quotes or two hyphens in my password? Or the words delete and select? What could this mean? It means there's an overzealous SQL injection prevention system in place, and it could mean that the website is storing passwords incorrectly.

Why it's bad: Again, you should never limit what a user can put in their password, as it decreases entropy and makes it easier for an attacker to brute-force. It also means that the password might be getting stored as plaintext, since hashed passwords would never contain the "invalid" characters or strings.

What it indicates: It could mean that the site is storing passwords as plaintext. A password with characters from SQL syntax could cause an injection attack, but this shouldn't be possible in the first place. Plaintext passwords should never have reached the database to begin with. It's possible that the site is still doing the right thing, but in that case it indicates that the developer (or the person that wrote the spec) doesn't really understand how to properly handle passwords.

How to fix it: Rather than placing this restriction on the user, the developer should have added an assertion to the database layer that requires that the password field only contain proper base64-encoded hashes of the proper length. And if passwords are not getting properly salted and hashed, that needs to happen.

Password case-insensitivity

There are three kinds of case-insensitivity:

The first two of these are fine: if done properly, it simply means that when the password was originally generated, it was modified and salted/hashed multiple times and multiple hashed passwords are tested on login. This is a technique that Facebook employs.

The last is a grave offense, and it almost always indicates that the website is doing the wrong thing.

Why it's bad: Removing case-sensitivity means that attackers have nearly half the characters to deal with when they're trying to crack a password.

What it indicates: Aside from passwords that are not properly salted and hashed, this could mean that passwords are being lowercased (or uppercased), which significantly decreases entropy. At worst, the site is using worst practices and at best, the site is decreasing the amount of work a hacker needs to do to crack a leaked password database.

How to fix it: If you aren't properly salting and hashing passwords, go do that right now. If you are, you need to start updating your system to be case-sensitive. If your database contains a hashed, forced-case version of a password, you need to update it when the user logs in with a hashed version of their cased password. This will have a substantial migration time if you have a large user base.

Passwords in email

This usually happens with very old server software like PHPBB. When you sign up or go through a password reset flow, you get an email containing your plaintext password. Nothing about this is good.

What it means: It means that the website doesn't care about the security of your password.

What it indicates: The site is either storing your password in plaintext or they're (obviously) passing your plaintext password through email. I would have to say that both are equally bad, as virtually all email is sent in an unencrypted form, and anyone intercepting the message with your plaintext password doesn't need to do any hacking work on the site to extract your password.

How to fix it: First off, stop. Never send a password via email. It should just never happen. Ever. Second off, if you have a plaintext password to send (i.e., for a password reset flow), it means you aren't properly salting and hashing. Go do that right now.

How can I protect myself as a user?

To all my fellow users/consumers out there, the first step is to go install this Chrome extension or this Firefox add-on. It will tell you when you're on a website that's doing a terrible thing with your password.

Next, get yourself a tool like Lastpass or 1Password so that you always have a unique password. If you choose not to use a password manager, keep your eyes peeled for any of the above bad habits. If you see them, change your password for that website immediately.

Lastly, if you see something, say something. Submit reports of this kind of authentication tomfoolery to sites like Plain Text Offenders. By spreading awareness and making this information public, you're not only helping those sites to become aware of their insufficiencies, but also helping your fellow users to avoid having their passwords stolen.