What is it and why should I care?
Authentication is the process of verifying that someone is who they say they are. Essentially a user claims an identity and then must provide some form of proof of identity. In most systems, the identity is some form of username and the proof is a password. In the simplest case, if the username and password provided match a user record known to the application, then the user is authenticated and proven to hold the claimed identity.
Authentication is one of the most important aspects of security within an application because it’s the starting point for most other conversations. Many security solutions start with the basic assumption of an authenticated user. That means we already got authentication right! Authentication is difficult to get right, but can be done.
What should I do about it?
I’ve already written down a few ideas about authentication in a previous series, but I’ll try to add a few additional ideas here.
Let’s start with a few easy ones that most people are very aware of.
Authenticate over a secure channel. For the web, this means SSL/TLS. Performing authentication over an insecure channel makes intercepting credentials trivial (unless other encryption mechanisms are used). This is an easy win.
Provide logout feature. Once you’ve logged in, you need to be able to logout. Putting a logout link/button on every page in an easily visible place makes it simple for your users to terminate their authenticated session when they please.
Provide related functions. If you provide an authentication function within your application, that means you’ll need to give your users a mechanism to update their credentials (passwords, tokens, etc.). For the common case of passwords, you’ll need to provide additional functions such as password change and reset. In addition, you’ll want to have an account lockout process to prevent brute-forcing of your authentication system. There are other functions you could add, but these are a good base set. These functions are also easy to get wrong, so pay attention to their implementation.
Use generic error messages. You’ll need to ensure you don’t leak information with error messages within the authentication subsystem. The classic example is someone logging in with a bad username and password and being told “user does not exist” versus logging in with a good username and bad password and being told “password does not match”. Here, you’ve leaked that a user exists with that username, so you just have to guess their password and you should be in. What should be done is the user should be given a generic error message like “Authentication failure” and that way, you can’t determine what the issue was.
Update (8/15/2012): There is far less benefit for generic error messages in systems where users can easily register for their own usernames, thereby circumventing the knowledge gap of whether or not an account actually exists.
Handle session management properly. Session management is a topic in and of itself. For J2EE folks, unless you have a good reason, you should be using the built-in session management capabilities of the platform (jsessionid). This is a solid implementation that you don’t have to build yourself – use it. One note here that is beyond this topic is stateless session management (think REST). Here, there are generally well-known practices (like http basic auth for REST) that are used instead of built-in session management. Just be aware of the systems you’re using, and consider their security implications.
Consider single sign-on. Single sign-on can be a helpful option if you’re in an organization that has a good implementation. Most of them work in a simple way. The user is authenticated by either being redirected to a common authentication function, or by each application accepting credentials and using these to authenticate against a single user repository. Either way, the actual user storage and authentication processes should only have to be built once, which is a good thing for reuse. This just makes it all the more important to get the process right.
Update (8/15/2012): While SSO does have it’s uses, there are some concerns.
- You’ve now got a much larger repository of users all coming through a single point of failure, not to mention the increased risk of losing all of your accounts at once.
- You are also granting access across all applications (regardless of security requirements and risk tolerance) with a common time-out, as well as other services which are provided by the SSO implementation. There are situations where you certainly might want to choose the features and configuration of your authentication system depending on the risk profile.
All of these issues should be weighed, both good and bad, when considering an SSO implementation.
Now let’s discuss a few of the less frequently implemented ideas.
Re-authenticate high value transactions. If you’re application has an important transaction that needs to take place with an already authenticated user (e-commerce purchase, wire funds transfer, view medical records), you should re-authenticate the individual transaction. This ensures the user viewing your site at that moment has been properly authenticated. This can help prevent issues where users step away while still involved in an authenticated session and another user being able to use the system as the originally authenticated user.
Use multi-factor authentication. This is a costly measure, but can be a great way to increase security. Many online systems are starting to use a form of this by allowing you to have a code sent to your phone that you have to enter during the authentication process. That means an attacker would have to know (or guess) your password and have access to your phone in order to authenticate as you. This decreases the likelihood exponentially, and is an excellent option.
Outsource your authentication. In the last few years, it’s become more common to let others do your authentication for you. Essentially, you can forego the authentication system altogether, and let your users authenticate to your site by sending you an authentication / access token from a well-known authentication provider (like google/twitter/facebook). All the authentication goes on at those other sites, and you are just told “OK, we know this is Bill and here’s Bill’s access token.” As long as you check Bill’s token and it’s valid, then you’re good to go. This is not an option for many organizations, but if you’re building a site that could use one of these services, it can shrink the size of your application, and the general sense is that “those guys” do a better job at security than you would. In general, that’s probably reasonably fair for the big providers in particular. Most of these providers are using the OAuth protocol right now.
In conclusion, authentication is a critical piece of most any application. It can be difficult to get right, but the steps listed above should put you on your way to getting it right.
Update (8/15/2012): Updates were made to the doc based on helpful review and feedback by Jim Manico.