Web sites by their very nature are stateless. HTTP initiates a new connection every time a user clicks on a link within a site. Session cookies keep state by moving a user's preferences from page to page as long as the session is active. But how do you keep a Web site secure for the entire session a user has logged in? There are many ways to pass a session token securely, some of which still include using the venerable old session cookie....
Here are some dos and don'ts to protect users who are logged in, especially to secure sites, such as those for e-commerce, online purchasing and banking transactions.
The first rule is to create a secure logon from the start. Make sure that even the URL of your logon page is HTTPS and uses SSL. Otherwise, there's the possibility that logon credentials, such as user IDs and passwords, may be caught en route in clear text by sniffing from a plain unencrypted HTTP site. Starting with SSL encrypts from the beginning and protects those vital credentials.
Second, the best token for maintaining secure state is a session ID generated by the server. Make sure session IDs, which can be stored in session cookies or even URLs, are generated only by the Web server – not the client. Examples include JSESSIONIDs and ASPSESSIONIDs. Any token created by the browser is easy to capture and replay to spoof the user's identity. When the user moves to the next page in the application, all that is sent back by the browser – again by session cookie or URL – is the session ID, which can be verified by the server that generated it.
But, wait. The session ID can still be captured on the round trip and replayed in some cases, like when it's passed in the URL. So, all session IDs should be unique, random and encrypted. Unique means that every session should have its own session ID. So, even if the same user logged on twice, there should be two separate session IDs. And, in that particular case, the server should map the session ID to the user on the back end. If it's the same user trying to log on twice – a tell-tale sign of a malicious spoofer – the second user, innocent or not, should be blocked from accessing the Web site.
Session IDs should be generated randomly, so they can't be guessed. A favorite technique of hackers is figuring out session ID patterns, such as incrementing for each new user, and then replaying the pattern to gain access. And, of course, encrypt all session IDs with 3DES, MD5 or at least 128-bit encryption to keep sniffers clueless. Before encryption, it's a good idea to combine a timestamp into the session ID, which adds to its uniqueness, as well as making it more cryptic to begin with.
Finally, make sure all tokens, session IDs and session cookies expire after a reasonable time period -- between 20 minutes and an hour, for example, depending on the business requirements of your application. When the session has timed out or the user has logged out, clear out all tokens, whether session IDs or cookies, by deleting them on both client and the server. This way a session is completely dead and can't be brought back to life.
Using these same rules, it should be obvious that session tokens should never be put in hidden HTML fields or passed unencrypted as part of URLs. Follow the three rules of session tokens – unique, random and encrypted – and your users will use your Web site safely and securely.
About the author
Joel Dubin, CISSP, is an independent computer security consultant based in Chicago. He specializes in Web and application security and is the author of the recently released book The Little Black Book of Computer Security available from Amazon. SearchSecurity users can submit their questions to Joel via our Ask the Expert feature, or read an excerpt from his book.