We come across home-grown session management schemes in our security tests. At times developers misinterpret how to use session objects and painstakingly build their own schemes. These unfortunately turn out to be insecure - Balaji described one such instance in August.
Last week we came across yet another custom-built session management scheme.
The application was built on servlets, but did not use the built-in session management that servlets provide (using the JSESSIONID cookie). Instead, the developers wrote a fresh scheme using a cookie they named "user_session_id".
That by itself wasn't insecure - until the developers faced a roadblock in timing out inactive sessions.
The application needed a mechanism to figure out when a client was idle for 10 minutes and then timeout the session. Normally, this would be done by setting the timeout value for the session object at the server. But remember this application does not use the session object in the first place.
The developers looked around for a solution and then noticed the "expires" attribute of the cookie. They decided to use this attribute to manage idle sessions. Here's what they did: every time a page was served, they would update the expiry time of the user_session_id cookie and increment it by 10 minutes. The session cookie's expiry time thus changes with every new page.
Confusing? Here's the reasoning: the browser will not send a cookie to the server once the cookie has expired. And since the user_session_id cookie expires within 10 minutes of the page being served, the application has effectively implemented a session timeout feature. The server is not required to maintain how long a user is idle- that work has been offloaded to the browser.
This is however vulnerable to attack. An adversary who has access to the user's machine can steal a session if the user has not explicitly logged off.
Let's see how: first, note that the server does not proactively logoff a user after 10 minutes. Instead it checks the next request for the presence of the cookie to determine whether the user was idle for 10 minutes. Also remember that the session token is a persistent cookie and is stored in the cookies file. Third, though the browser will not serve cookies that are expired, the cookies file purges those cookies only periodically.
An attacker with access to a user's machine can thus get the user_session_id from the cookies file and hijack a session that is not logged off.
Alternately, if the attacker had access to the machine before the victim used it, he could change the system clock to an earlier time, say a week earlier. The server would set the cookie to the true current time plus ten minutes, which according to the client is 7 days away. That effectively prolongs the life of the cookie by a week. If the user then failed to press log off and just closed the window, the attacker could hijack the session at a later time.
Managing sessions can be quite complex; in general, it's safest to use the built-in session management scheme provided by mature web platforms than build one's own. To see how to implement even safer schemes, check out Sangita's paper on page tokens in the August issue of Palisade.