2
votes

Is there any way to load a specific user session by providing the correct value of CFTOKEN and/or CFID?

Something like php's session_id($id) function.

Or some way to change data of an specific session.

I need a webservice that will add or change some information on a specific user session. I know the CFID and CFTOKEN values because I share a subdomain cookie. However applications are on different servers

3
Are you looking to get a different session than the one one you are logged in as? - Tom Hubbard
What exactly are you trying to achieve? There is a java object that coldfusion uses to manage its sessions. You could use it to get info from any active session. If you want to get info, you need to use reflection too so you dont inadvertently extend their session timeout - Mike Causer
I need a webservice that will add or change some information to some user's session. I know the CFID and CFTOKEN values because I share a subdomain cookie. However applications are on different servers - zad
It´s ok to extend the session timeout. - zad

3 Answers

2
votes

Not that it's the best way of doing things, as it uses undocumented code that can change without notice between versions. But you can use certain methods to access sessions.

<cfscript>
    appName = 'zadsApp';
    jSessTracker = CreateObject('java', 'coldfusion.runtime.SessionTracker');
    appSessions = jSessTracker.getSessionCollection(JavaCast('string', appName));
    targetSession = appSessions[appName & '_' & sessionCFID & '_' & sessionCFTOKEN];
    // Dumping, reading, writing WILL update the last accessed time.
    // There are ways around this if needed...
    WriteDump(targetSession);
    targetSession.something = 'A new value';
</cfscript>

Now you mention that this is on a different server, can I just double check that you want a seperate server to change a session on another server? Without putting any kind of code like the above on that server (the one with the session)? Although it'd be a heck of a lot easier if the code was on the same server, you might be able to perform code like this remotely using JMX... but I'm sure there must be an easier way to do all of this.

2
votes

You can do it by passing the correct values on the URL, more information available here

http://ruthsarian.wordpress.com/2005/10/03/cf-session-hijacking/

ColdFusion uses two unique values to keep track of user session information. These values are CFID and CFTOKEN. They are stored as cookies but can also be passed along the URL and inside POST data.

Session variables are a place to store information specific to the user and to the current session (such as whether or not a user is logged in).

It is possible to hijack a user’s session by supplying the correct CFID and CFTOKEN values to the server, either on the URL, or wherever else you want.

What it sounds like you are trying to do is effecitvely described by this post http://old.nabble.com/ColdFusion-9-Session-Replication-td32621620.html which advises against session replication on grounds of high network usage due to it.

Where you are trying to maintain a specific sessions scope across multiple physical servers. The way I've worked around this in the past is to maintain a database storing the information which needs to be passed between physical servers tied to a UUID. For this purpose you could just use the CFID/CFTOKEN values as your database PK's, or you could make another PK altogether. This would then allow you to pass the CFID etc on the URL string, and then if it hits a server which it hasn't so far hit (i.e. no session / session wasn't loaded using those CFID/CFTOKEN) then you can load the variables you need from a database.

Edit an alternative non-database method

Firstly set up a script on one server i.e. getSessionData.cfm which returns the data in the session scope in transportable format i.e. using SaveObject() (if on CF9), or maybe SerializeJSON(), something like that

<!--- on source server, getSessionData.cfm --->
<cfscript>
    WriteOutput(ToBase64(ObjectSave(session)));
</cfscript>

Then set up a handler that will request data from the other server using a cfhttp request populating CFID/CFTOKEN to access the session, and then pull that data into the session on the new server.

<!--- on target server --->
<cfhttp url="http://sourceserver/getSessionData.cfm">
    <!--- Params to pass through CFID/CFTOKEN or any other cookie/url/post params etc --->
</cfhttp>
<cfscript>
    structToImportToSession = ObjectLoad(ToBinary(cfhttp.FileContent));
    for (thisStructKey in structToImportToSession) {
        session[thisStructKey] = structToImportToSession[thisStructKey];
    }   
</cfscript>

The problem with this is that I would feel uneasy with this kind of script being on my server in a production environment. It also means that you will need to know explicitly which physical server the user came from so that you can request the getSessionData.cfm script from the correct server.

This post from Ben Nadel seems to employ a similar principle to update session data, same could be applied for updating it I expect, http://www.bennadel.com/blog/725-Maintaining-Sessions-Across-Multiple-ColdFusion-CFHttp-Requests.htm

Personally I'd still advise the database-drive method as it gives you clearer mechanics by which to purge old sessions etc, however this second option should be viable and give you access to what you need.

0
votes

as long as the session isn't expired you can access a session by using the CFID and CFTOKEN in the url