John Melton's Weblog
Java, Security and Technology

Year Of Security for Java – Week 30 – Authentication

No Gravatar

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.

References
———–
https://www.owasp.org/index.php/Authentication_Cheat_Sheet
https://www.owasp.org/index.php/Top_10_2010-A3-Broken_Authentication_and_Session_Management
https://www.owasp.org/index.php/Guide_to_Authentication
https://www.owasp.org/index.php/Testing_for_authentication
https://www.owasp.org/index.php/Session_Management_Cheat_Sheet
http://www.jtmelton.com/2010/06/16/the-owasp-top-ten-and-esapi-part-8-broken-authentication-and-session-management/
http://oauth.net/

Technorati Tags: , ,

The OWASP Top Ten and ESAPI – Part 7 – Broken Authentication and Session Management

No Gravatar

This article will describe how to protect your J2EE application from Broken Authentication and Session Management issues using ESAPI and other techniques. As with all of the detail articles in this series, if you need a refresher on OWASP or ESAPI, please see the intro article The OWASP Top Ten and ESAPI.

What’s the problem?

What does Broken Authentication and Session Management mean? As usual, let’s check in with what OWASP says:

“Flaws in the main authentication mechanism are not uncommon, but weaknesses are more often introduced through ancillary authentication functions such as logout, password management, timeout, remember me, secret question, and account update.” [from here] They go further to say the goal in resolving these types of issues is “to verify that the application properly authenticates users and properly protects identities and their associated credentials.”

The idea here is that of providing assurance that a given user can gain access to their account if one exists, and only that account. This is a complex topic that covers many aspects, only some of which we’ll be addressing here.

If this issue is not properly addressed, various problems arise. These can include accounts being hijacked, credentials stolen, data being compromised, etc. Beyond the issue of losing data, there is obviously a huge reputational risk with these types of issues as well. Essentially you are dealing with the keys to the kingdom – if they’re lost – noone trusts your application!

Where do we go from here? ….

Now that we’ve briefly discussed what can occur if this issue is not addressed properly, let’s talk a bit about some steps we can take that can remediate the issue when properly applied. For this section, I’ve heavily used this article.

1. Use the built-in session management features. Session management is difficult to get correct. Even though app servers have been doing it for years, there are still bugs being reported with reasonable frequency. It is foolish to think that you’ll do better on your first try.

2. With regards to authentication:
- Use a single entry point. Don’t write and rewrite auth code – write it once, and try to get it right
- Make sure login starts on an SSL-protected page.
- Invalidate the HttpSession before login and after login. This helps prevent session fixation attacks where an attacker can specify a session id for a user to use. Invalidating the session id guarantees the attacker doesn’t have access to the new session id.

3. Get logout right. Make sure it’s accessible throughout the application with a single click, and make sure it invalidates the session and anything else that may be being used in the auth process, such as a cookie.

4. Add a timeout. A session timeout (and associated handler) should be configured to grab sessions that have timed out and clean them up so they are not available for reuse. Obviously, the shorter the time for the timeout, the less risk – the longer the time, the more user friendly. Find the balance you need for your application – personal opinion – 30 minutes is often plenty of time for many sites with anything valuable on them.

5. Ensure you are using safe related functions. Functions like security questions and answers, forgot password, forgot username, change password are difficult to get right. When done improperly, they can leak information about the account, and outright cause loss of credentials. Be sure to find as much information as you can about how to get these functions right before implementing them. Then test them to death – both unit tests and functional tests.

6. If you’re in a situation where it’s possibly, use strong authentication. This would mean using 2 or more of the 3 possible factors: something you know, something you have, and something you are. Typical username/password (something you know) systems are prevalent, but if you could add a token (something you have), then you levy an additional requirement on the user, but you also reduce the risk of someone gaining access that shouldn’t (assuming your authentication is sound).

7. Default to not authenticated. It sounds simple, but folks do (more often than you might think) code systems that default to authenticated on login. The code would look something like this:


//BAD - DON'T USE
public boolean login(String username, String password) {
    boolean isAuthenticated = true;

    try {
	//make calls to backend to actually perform login against datastore
      	
  	if (! authenticationSuccess) {
	    isAuthenticated = false;
	}
    } catch (Exception e) {
	//handle exc
    }
    return isAuthenticated;
}

As you can see, the user is set to authenticated by default, and if an exception is thrown, the user is logged in. This would fall under the security mantra of secure defaults. Unfortunately code like this is surprisingly common in systems today (but hopefully not yours).

OK, well that’s all I’ll cover in this article. Let me add just one more simple word of caution: authentication and session management are difficult and complex topics. It is very naive to think that you will get it right on your first try. Please consult with folks like OWASP and other secure development resources to get a broader picture of the types of issues that need to be addressed in this space. Educate yourself as much as you can. Use other’s good code that’s been vetted if it’s available. If not, take your time – think through the types of attacks that are possible, do code reviews, get others to do code reviews, and test test test.

Well, that’s it. Hope you’ve found this article helpful. Let me know if you have any questions or suggestions. Feel free to comment on techniques you are using to correct Broken Authentication and Session Management issues.

Other articles in this series:
Part 0: The OWASP Top Ten and ESAPI
Part 1: The OWASP Top Ten and ESAPI – Part 1 – Cross Site Scripting (XSS)
Part 2: The OWASP Top Ten and ESAPI – Part 2 – Injection Flaws
Part 3: The OWASP Top Ten and ESAPI – Part 3 – Malicious File Execution
Part 4: The OWASP Top Ten and ESAPI – Part 4 – Insecure Direct Object Reference
Part 5: The OWASP Top Ten and ESAPI – Part 5 – Cross Site Request Forgery (CSRF)
Part 6: The OWASP Top Ten and ESAPI – Part 6 – Information Leakage and Improper Error Handling
Part 7: The OWASP Top Ten and ESAPI – Part 7 – Broken Authentication and Session Management
Part 8: The OWASP Top Ten and ESAPI – Part 8 – Insecure Cryptographic Storage
Part 9: The OWASP Top Ten and ESAPI – Part 9 – Insecure Communications
Part 10: The OWASP Top Ten and ESAPI – Part 10 – Failure to Restrict URL Access

Technorati Tags: , , , , , ,