Secure Development - Session Management

Mar 30 2010

Last time, we talked about access control, which typically happens once a user is authenticated and a session is established. Today, we'll go into more details on the session management processes itself. I was originally going to include authentication in this discussion as well, but the blog entry started getting really long. I will write a separate post on authentication issues next time, and for now we'll talk about web application session management.

Under the hood, all web applications use HTTP for client-server communication, which is a stateless protocol by design. In other words, a standard web server has no concept of session history; it sees all page requests as completely separate, even if they come from the same browser or IP address. The majority of web applications require some form of persistent "memory" of what the user has already done; otherwise the user experience would be horrible: either all data would have to be entered on a single page (no shopping carts, multi-step checkout, etc.), or the user would have to re-enter his login and password for every page.

At a very basic level, this problem can be addressed by a feature called HTTP authentication, which can also serve as a basic form of session management. This prompts the user for the login and password once, which are then cached by the browser and re-submitted automatically with each request. There are some severe security problems with this approach: the username and password are only encoded (using Base64 encoding)--not encrypted--which means they are essentially transmitted in plaintext with every page request. There is also no standard way to tell the browser to discard the cached credentials (other than restarting the browser), making it impossible to log out easily. Due to these issues, HTTP authentication should never be used in a widely-deployed web application, especially when users can access pages without using HTTPS.

In a vast improvement over basic HTTP authentication, all web application servers support some form of standard session management, which creates a layer of "session memory" (called persistence) on top of the HTTP protocol. The implementation details vary between vendors and technologies, but the basic concept is the same: HTTP cookies with session identifiers are typically used to tie separate requests to a single session. Similar to HTTP authentication credentials, the cookies are cached by the browser and are re-submitted with every request. However, the session data itself never leaves the server: it's stored in a set of session variables that are cached on the server, indexed by session ID. It is possible to store data directly in cookies, but this is not considered to be a good practice, especially for sensitive information.

It's important to note that session management can be used both with and without authentication. As I mentioned in my last post, most e-commerce websites let users shop with an unauthenticated (anonymous) session and only require authentication once the user is ready to check out. This scenario can easily lead to a session fixation attack if not implemented correctly. The attacker first creates a new, anonymous session and sends a link to the victim with the session ID embedded. If the victim now clicks on the link and logs into his account using the same session ID, the attacker can then easily hijack the authenticated session because he already has the session ID (he fixed it in advance).

To guard against this attack and other session-related security issues, you can use the following techniques:

  1. Standard session management: Most likely, your web application platform/framework of choice provides a standard method for doing session management. Use this functionality rather than "rolling your own." This way, you save time and avoid implementation mistakes.
  2. Use encryption when possible: If possible, use SSL/TLS (HTTPS) for all non-public parts of your application. This way, session IDs are not transmitted in cleartext, which protects against some session hijacking attacks. Additionally, SSL protects the content of the user's transaction against prying eyes, especially when they are on public wireless networks where traffic sniffing is trivial. SSL (or some other form of strong encryption) is required during the authentication phase to protect the username and password; more on that in the next post.
  3. Session timeouts: Sessions should automatically time out after a certain period of inactivity, and there should also be an absolute session length time limit, regardless of activity. This prevents an attacker from hijacking an active session during the small inactivity window and then keeping it alive indefinitely by refreshing pages at regular intervals. Setting the proper session timeout values is also important for server-side resource management, especially if your application has thousands of users. Since each session takes up a small amount of memory/storage on the server, leaving unused sessions active too long can cause problems.
  4. Don't reuse session IDs: The root cause of the session fixation attack is the fact that the same session ID is re-used once the user is authenticated. This is convenient for the developer since some session state needs to be brought forward (shopping cart contents, etc.). To better handle this situation, always generate a new session ID once the user authenticates. Depending on your framework, you may be able to simply "re-key" the existing session with a new ID, or you may have to create a new one and copy the necessary data across from the old session.
  5. Use server-side session variables, not client-side cookies: Store your application data in server-side session variables, especially if it's sensitive information. Storing data in client-side cookies could allow an attacker to discover implementation details about your application (variable names alone can be a gold mine of information...) and it also allows him to manipulate the cookie values. If you do use cookies to store data (this can sometimes be helpful for performance reasons), be sure to treat this as you would any other user-controlled input: use proper input validation and error checking.

So far, we have talked about proper access control and session management, which are essential to almost all web applications. To tie these two together, we need a solid authentication approach--more on that next time.

 

About the Author

Daniel is a business and technical systems analyst with a background in IT security and software development. He has six years experience in the IT security field, including published academic research. His main areas of expertise include software assurance, network security, and authentication. In addition to security, Daniel has a software development background in languages such as Java, Perl, SQL, and PHP. He also has 14 years experience working with and administering various versions of Linux and related open-source software.

 

Disclaimer

The words and opinions expressed here are those of each article's respective author, and do not necessarily represent the views of CapTech Ventures.