Session data not being stored

Anybody have any idea for reasons why session data would not be saved
across requests (like, the very definition of session data)?!

I get to a certain page in my process and my home-grown CSRF validation
stops working. With each page request I check to see if a token for that
page is stored in the session scope. If not, I create the token, store it
in the session scope, submit the token through a hidden form field, then
check the hidden form field against the token stored in the session scope.
Standard stuff.

if (!isDefined(“session.tokens.employee.contributions.token”)){
“session.tokens.employee.contributions” = {
“token”: LCase(Hash(
#CreateUUID()#employee.contributions#RandRange(10000,99999)#”, “SHA-256”)),
“expires”: dateAdd(“h”, 2, Now())
}
}

if (session.tokens.employee.contributions.token != form.csrftoken){
variables.isValidToken = false;
}

What is happening is that, when I submit the form, the page does not find a
token for that page in the session scope so it creates a new token. Since
the new token doesn’t match the form token, then isValidToken is false. But
it’s only happening once I get to this stage in my process, never earlier.

So I decided to try using CSRFGenerateToken and CSRFVerifyToken instead but
I am finding the same result. Even when CSRFGenerateToken has forceNew set
to false, a new token is being generated for the key on that page.

My sessions have nested structs in them and I briefly considered that the
name “session.tokens.employee.contributions” was somehow reserved. I’m also
using cfml sessions, a datasource for session storage, and sessionCluster =
true. This is happening in multiple environments (dev, uat, demo) which are
all similarly configured but run on different hardware.

Any ideas? On dev I’m running:

Version Lucee 4.5.2.017 final
OS Mac OS X (10.11.2) 64bit
Servlet Container Apache Tomcat/8.0.15
Java 1.7.0_65 (Oracle Corporation) 64bit

I can see that the session data is not being stored to the database. Any
reason why this should be the case?

Thanks!

Looking at this a little closer, before checking the session token, there’s
a case where I’m logging an error to my BugLogHQ server. Since it’s an http
request, I run that in a thread:

thread name=“errorReport” {
application.bugLogService.notifyService(message=“The default date for
the account is invalid.”, extraInfo=form, severityCode=“INFO”);
}

It appears that, if I start a new thread, the current page session is not
written to the database. Or, maybe it’s a race condition and both the main
thread and the errorReport thread both cause the session scope to be
written to the database with the errorReport thread winning out.

Will test and update.

OK. Now I’m pretty sure that the issue is that a cfthread call overwrites
the session scope.

The attach code outputs the session scope via cflog. If there is no delay
in the thread, then there is no issue. You can hit submit to your hearts
content. But if I introduce a delay (in this case via url.sleepTimer), then
a running thread eventually overwrites the session scope with the version
that it had when it was run. In the code that revealed this problem, the
delay was introduced by an http call within the thread.

I’m honestly not sure if this is expected behavior or a bug. Should a
thread be able to write to a shared scope after the requesting page
finishes processing?

Note that this problem only occurs when this.sessionCluster=true.

20151104.cfm (3.11 KB)