Sessionrotate() with load balancer causing issues

We use a load balancer in front of a couple of servers, with sessions
stored in the database and no sticky sessions. We recently had security
consultants recommend we add a sessionrotate() when a user logs in, but
when we do this the session only works on the server that the user logged
into.

How does that work? I expected that after a sessionrotate() that the new
cookie would identify the same session on all servers.

Is there a workaround for this that doesn’t involve adding sticky sessions
or losing the sessionrotate()?

Thanks… Simon

The issues seem to have something to do with the combination of database
storage of session data and the sessionrotate() function. With the load
balancer out of the equation, we experienced sessions rotating themselves
before they were due to expire. When we change the session storage to
memory, the problem goes away.

A sample of records in the cf_session_data table shows that after rotating
the cookie, the sessionid is updated but the cfid remains unchanged:
expires cfid name data
1450404504648 a5fabe28… myapp
{‘timecreated’:createDateTime(2015,12,18,11,57,48,346,“Australia/Sydney”),‘sessionid’:‘myapp_1dfcc378…’,‘lastvisit’:createDateTime(2015,12,18,12,8,24,611,“Australia/Sydney”)}
1450405537147 1dfcc378… myapp
{‘timecreated’:createDateTime(2015,12,18,12,25,37,154,“Australia/Sydney”),‘sessionid’:‘myapp_85725018…’,‘lastvisit’:createDateTime(2015,12,18,12,25,37,126,“Australia/Sydney”)}

After a short while, much less than the session expiry, a new session
appears in the database with the cfid of the cookie that was generated when
the session was rotated. The sessionid is updated after I sessionrotate()
and set the session variables in the login procedure:

1450405909758 85725018… myapp
{‘timecreated’:createDateTime(2015,12,18,12,31,49,757,“Australia/Sydney”),‘sessionid’:‘maypp_85725018…’,‘lastvisit’:createDateTime(2015,12,18,12,31,49,757,“Australia/Sydney”)}

Relevant records in the Application.cfc:




Are we doing something wrong or is there a problem storing session data in
a datasource?

Thanks,
Simon

A couple of observations:

  • If you use a datasource for your session storage, always set the
    sessioncluster setting to true for your application (in Application.cfc:
    ) otherwise Lucee will use memory for
    session storage for a period of time before looking to your datasource,
    which seems to defeat the purpose of using datasource storage. I would have
    thought that if you specify a datasource for your session storage,
    sessioncluster should be true by default, but it isn’t.
  • With sessioncluster set to true, sessions fail immediately after a
    sessionrotate(), which simply doesn’t work with datasource storage.

So sessioncluster will allow you to do away with sticky sessions, but you
need to find another way to rotate your sessions.

Hey Simon,

I’ve never found the built-in session management functions of CFML to
behave well except in very basic situations. Sticky sessions and database
session storage rarely work as expected. I’ve been rolling my own session
management solutions for years and find the custom solutions to be both
more reliable and more robust than the built in functionality. It does
require a few extra steps, but it’s worth it. I have an example of a basic
implementation of my mechanism on GitHub. It’s built around framework one,
but the principles are the same regardless of the underlying
application… GitHub - ddspringle/framework-one-secure-auth: An example fw/1 application with secure single and two-factor (2FA) authentication and session management functions

The session management code is in SecurityService.cfc
(framework-one-secure-auth/SecurityService.cfc at master · ddspringle/framework-one-secure-auth · GitHub)
starting around line 267. This example uses the local cache, but you can
easily modify this to use a database table instead, or use the cache and
fallback to a database table (which is what I currently do in my production
work).

Session auth/reauth, including rotation, happens in the security.cfc
controller under admin
(framework-one-secure-auth/security.cfc at master · ddspringle/framework-one-secure-auth · GitHub)
within the authorize() function. This automatically handles populating the
SESSION scope with a session bean based on the data stored (in cache or
database) so when the user bounces from server to server the session data
is maintained, etc.

I’m currently working on a security guide for cfdocs that goes into more
depth on how this style of auth works (and a lot of other security related
things), but hopefully these examples will help point you in the right
direction until I can get that completed… in case you want to go the roll
your own solution route.

Hope that’s helpful.

– Denny