This post is part of a multi-part series. It builds on the first post, where I describe the framework we will use to evaluate authentication schemes. If you have not, it is probably a good idea to read it now (hint).
Here is where we are.
- I. What to look for in an authentication scheme?
- II. Evaluation of standard authentication schemes
- III. Cheatsheet and closing thoughts
II. Evaluation of standard authentication schemes
The good old HTTP Basic Auth
"I'll just throw a Basic Auth on it, and I'll be fine..."
Ever heard this? What was your reaction? Here are the two major types of responses I hear.
- You what? That's crazy; Basic Auth is for kids!
- Yeah, sure, you'll be alright!
I can't help smiling a bit when I encounter either. Basic Auth is ancient tech (from 1999). We still have not converged on a single opinion. Why do you think that is? Read on to find out!
How it works?
Since HTTP is a stateless protocol, the only way to authenticate, without relying on other protocols, is to attach something to each request. Precisely what Basic Auth does. It adds the following header.
Authorization: Basic base64(username:password)
One can immediately see, that the password is transmitted with every request, in clear text. RED FLAG!
But wait, is this a problem? As always, it depends, but more on this later. Let's continue by looking at Basic Auth based on the framework we set up earlier.
HTTP Basic Auth is simple; I truly mean simple. Some common web servers (Apache, nginx) include out-of-the-box support. There are tons of libraries available to help you use it. Without question, Basic Auth is easy to set-up and use.
Reliance on HTTPS
Basic Auth must only ever be used over HTTPS. Should it fail to provide confidentiality, this auth scheme fails badly as every request includes cleartext credentials. These can easily be reused by an attacker once he gets his hands on it.
If used between users and websites, Basic Auth credentials are managed by the browser. Once a user types in his credentials, the browser will automatically attach them to future requests. CSRF protection is required.
When used on the backend, CSRF is not a problem.
Replay and integrity protection
Basic Auth provides no replay or integrity protection at all. It completely relies on TLS for that. Again, only use Basic Auth over TLS.
Recommended use cases
The simplicity of Basic Auth is its edge over the other schemes. It provides the bare minimum. It works on both the frontend and the backend. And contrary to popular belief it is perfectly fine to use it in some scenarios.
Let's see when.
Use Basic Auth for user authentication only if you are positive you do not need session management. This is important. Basic Auth utterly fails the criteria for session management. Sending the user's credentials with every request is a no-go. To add to that, logout is rather complicated, and miles away from being user-friendly.
A great frontend usage would be a read-only resource, like a document. Sometimes you can get away with using Basic Auth for the initial prototype of your application. Just make sure to upgrade it when needed.
Frontend usage also comes with CSRF. Take a minute and think about it as Basic Auth is vulnerable by default. Implement protection if deemed necessary.
The backend is a little different. Here, Basic Auth's base64 encoded string can be considered an opaque authentication token. In fact, I have seen APIs designed with this in mind. They require you to use your API key as a password, and they do not care about the username. Guess what? It is okay. If TLS does its job you are good to go.
Taking care of your auth scheme
Keep in mind the following tips when deploying Basic Auth. First and foremost, do not implement it yourself. I know, it is dead simple, but still, if you can, use a well-established library.
Second, if you use it on the frontend, user credentials are sent with every request. Good practice requires you not to store the user's credentials in clear text. Luckily Basic Auth does not stand in the way here, as the plaintext credentials are never used server side. Consider hashing the passwords with a modern hash function (bcrypt, scrypt, argon2) and only storing the resulting hash.
Third, never use Basic Auth over a plaintext connection. Think of that as shouting your password across a cafe full of people. You simply don't do such a thing.
Coming up next
Basic Auth was the warm-up and now you are ready for the workout. All the following schemes are more complicated and provide further functionality.
Our next stop is the lesser-known Digest Authentication. Back in the day, it was meant to be the next-generation Basic Auth. Did it succeed? Should you opt for digest instead of basic? Read the next post to find out.
Spot a mistake in reasoning? Have a different opinion? Sound off in the comments!