A web application is vulnerable to a session fixation attack if an unauthenticated user’s session ID does not change after authentication. A malicious user could start an unauthenticated session and give the associated session ID to the victim. Once the victim authenticates, the malicious user now shares that authenticated session.
ColdFusion introduced SessionRotate in CF10 to mitigate such attacks. However, it only applies to CFID and CFTOKEN (ColdFusion sessions). If you are using J2EE sessions, there is no SessionRotate. This is unfortunate, as the ColdFusion documentation has stated for years that J2EE sessions have advantages over ColdFusion sessions (see Configuring and using session variables), the foremost being that J2EE sessions are not persistent. It’s also unfortunate, because this is an important security-related tag that only works under certain server configurations–and fails silently under others!
As a side note, J2EE has been called JEE (Java Enterprise Edition) since Java 1.4. The ColdFusion administrator continues to refer to it as J2EE, but you are likely to see references to JEE in reference material online.
Session rotation basically consists of:
- Deleting the user’s current session
- Creating a new session containing the same data, but with a different ID
Jason Dean at 12robots.com wrote about mitigating session fixation on ColdFusion in Session token rotation REVISITED and other articles. His posts were helpful in explaining the issue and offering a solution for rotating ColdFusion sessions on pre-CF10 systems. However, he posted no solution for JEE sessions.
But according to the CF documentation on Ending a session: You cannot destroy the session and create a session on the same request, as creating a new session involves sending session cookies back.
That’s problematic. Once a user authenticates, we can destroy the user’s session. But how do we create the new, authenticated session?
An answer posted in response to ColdFusion Session Fixation on StackOverflow suggests the solution is to store necessary data in a secure way and pass the data, or a token associated with that data, on to a new HTTP request. I considered, for example, generating a UUID as a nonce and storing it in a database along with the username and a near-future timestamp. The user would then be directed to a URL with the nonce appended as a token, which could be validated against the database to authenticate the user.
Fortunately, a simpler solution exists. Pete Freitag posted SessionRotate solution for JEE Sessions in March, 2014. By accessing properties of the Java servlet session running under ColdFusion, his methods perform the following steps:
- Copy the session scope into a temporary variable
- Remove the ID and URL tokens from the temporary variable
- Invalidate the existing session
- Create a new session
- Copy the attributes of the temporary variable into the new session
The final step is somewhat more complicated, as the new session is apparently not immediately available, and copying the attributes happens in the Application.cfc’s OnSessionStart. Still, it can happen in a single request! The JEE documentation on Creating and Managing User Sessions has more information about the underlying JEE sessions.
When I implemented Pete Freitag’s solution, I made the following modifications:
- I created a jeeSession.cfc containing:
- rotate (originally named jeeSessionRotate)
- copy (containing most of onSessionStart)
- I created jeeSecureApp.cfc containing:
- onSessionStart
- an instance of jeeSession.cfc
I can modify the cfcomponent tag in the Application.cfc of any app to include:
extends="jeeSecureApp"
Then jeeSession.rotate() is available.
Caveats:
- If your application already extends a CFC, you’d have to adjust this approach.
- If your application already defines an onSessionStart, you’d want to add a call to super.onSessionStart
I have a coldbox app and I’m having some type of session/cookie issue in prod. I’m looking for someone to do a paid consult with me to help resolve the issue.