Coldfusion load session from Id - coldfusion

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

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.

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.

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

Related

JMeter - Changing a Cookie's Value during a Test?

I have created a test plan in JMeter *(Version 2.13). I was able to add a Cookie Manager to the plan and have my cookies preserved between HTTP Requests, which works just fine.
What I'm trying to do now is, if possible, preserve one Cookie from the start (*Called "JSESSIONID") and then have another Cookie (*let's call it "MYID") which can be modified during the test.
My 1st try at this was like the following:
+Thread Group
-HTTP Request Defaults
-HTTP Cookie Manager
+HTTP Request - Goto HomePage
-HTTP Cookie Manager - Set MYID="server_1"
+HTTP Request - Load Login Page
-HTTP Cookie Manager - Set MYID="server_2"
....and so on for about 3 more HTTP Requests....
But, doing it this way only kept the original Cookies which were captured by the initial Cookie Manager which was set right under the Thread Group element.
Apache's site warns that:
"If there is more than one Cookie Manager in the scope of a Sampler, there is currently no way to specify which one is to be used. Also, a cookie stored in one cookie manager is not available to any other manager, so use multiple Cookie Managers with care."
Another test I did, that was similar to the first except I added a User Defined Variables element to the start of the test which had a variable for the MYID Cookie set to one server, and then about 2 or 3 HTTP Requests down I had a second User Defined Variables element, this time setting the variable to another server. But, after reading a bit more on the User Variables, JMeter only reads User Defined Variables ONCE, at the beginning of the test. So the variable I set last would remain as whatever I set it to in the 2nd User Defined Variables section. So that way won't work to change the Cookie value during the test...
I also, read this from ApacheJMeter's site, here Using Variables to Parametrize Tests, which seems closest to what I am trying to achieve. But, from their example it seems as though it's for modifying variables before the test starts, like for example setting a variable from the command line...
Summary:
To sum things up, what I am trying to achieve is to send my HTTP Requests with 2 Cookies:
1. JSESSIONID
2. MYID
Where JSESSIONID will remain the same from the very start, and MYID which I want to change it's value during test *(multiple times if posible).
Let me know if that does not make sense and I will try and explain further.
Any thoughts or suggestions would be greatly appreciated!
Thanks in Advance,
Matt
You can use Beanshell scripting for cookies manipulation as:
Add a Beanshell PreProcessor to your HTTP Request
Put the following code into the PreProcessor's "Script" area:
import org.apache.jmeter.protocol.http.control.Cookie;
import org.apache.jmeter.protocol.http.control.CookieManager;
CookieManager manager = sampler.getCookieManager();
for (int i = 0; i < manager.getCookieCount(); i++) {
Cookie cookie = manager.get(i);
if (cookie.getName().equals("MYID")) {
cookie.setValue(vars.get("foo"));
manager.remove(i);
manager.add(cookie);
break;
}
}
Above code will substitute "MYID" cookie value with "foo" JMeter Variable value via direct calls to CookieManager class (see API documentation for all possible methods and fields)
Check out How to use BeanShell: JMeter's favorite built-in component guide for advanced information on Beanshell scripting in Apache JMeter.

ColdFusion 10 not writing to cfcookie on same browser but different computers

I am migrating websites from a server using CF 8 to a new one using CF 10. In this one site, I have a query that looks up talent and then writes the resulting list to a cfcookie. On my computer with any browser it works correctly. My client uses the same browser as I normally use (Safari) and his browser is not updating the cfcookie with the new talent list after a search. They are very unhappy making me unhappy also. Any ideas as to what might be causing this problem.
In the application.cfm (yes, I know I should be updating to cfc but not enough hours in the day):
<CFAPPLICATION NAME="lil"
CLIENTMANAGEMENT="yes"
SESSIONMANAGEMENT="yes"
SESSIONTIMEOUT=" #createTimeSpan(0,0,30,0)#"
APPLICATIONTIMEOUT=" #createTimeSpan(0,1,0,0)#"
clientstorage="cookie">
Setting the cfcookie:
<cfif isdefined('getTalent.recordcount') and getTalent.recordcount gt 0>
<cfcookie name="tSearch" value="#valueList(getTalent.talentID)#" httponly="true" expires="1">
</cfif>
How large is the amount of data you are storing in the cookie, and could the client be storing more than you are? Are they possibly using a cookie-blocking security app of some kind?
In a bigger-picture kind of mindset, if the user is doing a search and getting results, rather than storing the results in a cookie, why not use either a session-scoped variable, or simply use the CF identity cookies already in place to store their results in a temporary database location? Cookie issues can be harder to track down, but unless you're not managing sessions in your Application.cfc or cfapplication tag, each user is already getting a unique ID which you can leverage server-side for this type of thing.
One last thought... are you doing any sort of CFLOCATION redirect, after attempting to store the cookie? Redirecting can cause CFCOOKIE commands to not be honored, because in essence the user's browser is redirected before it receives the response.

Importing Firefox and Chrome cookies to libcurl

I'm using Code::Blocks with MinGW, under Windows 7.
I'm writing a multithreaded web crawler with libcurl, using a CURLSH object with CURL_LOCK_DATA_COOKIE enabled to share cookies among different threads.
Once a handle receives a cookie, it is successfully shared among every other handle. However, I need to copy the initial set of cookies from Firefox or Chrome. I found that they store cookies using sqlite, and I've been able to read cookies from both of them from within my program. The problem is, how do I give these cookies to libcurl? Ideally, there should be some way to feed these cookies to my CURLSH object, so that they get distributed to every handle. I have found no such thing.
Following this document, I can try to save the cookies I read from my browser to a cookies.txt file, which reduces to finding a correspondence between the fields in the database used by Firefox/Chrome and the Netscape format.
Netscape uses the following format:
domain flag path secure expiration name value
The problem comes with the flag field. I don't know what to write there. Firefox uses the following fields (file cookies.sqlite, table *moz_cookies*), which correspond with the Netscape format as follows (is this correct?):
host ??? path isSecure expiry name value
Chrome uses the following fields (file Cookies, table cookies):
host_key ??? path secure expires_utc name value
So, to create this cookies.txt file, I'm only missing that flag field. The document linked above says:
flag - A TRUE/FALSE value indicating if all machines within a given domain
can access the variable. This value is set automatically by the
browser, depending on the value you set for domain.
Which doesn't really tell me what to write there.
However, writting a file and then reading it seems like unnecessary work, given that I'll first load the cookies from Firefox/Chrome in RAM, and I should be able to give them to libcurl directly without going through the hard drive. I've found the CURLOPT_COOKIE option, but it is missing some fields (namely, domain). Also, that option doesn't seem to save the cookies for posterior use. It looks like I would need to call it for every transaction with only the cookies of the corresponding domain (and what if these cookies get changed? I would not want to check for changes manually, given that libcurl can do that).
So, given that I have all my cookies from Firefox/Chrome in memory, how do I give them to libcurl? If the only option is to use a cookies.txt file, what should I write in the flag field?
I've found the answer, with CURLOPT_COOKIELIST (I was confusing it with CURLINFO_COOKIELIST, which can only be used to read cookies). Using CURLOPT_COOKIELIST, I can enter my cookies as HTTP headers, which do not need that flag field. I'll only need to give format to the date. It looks like specifying the cookies for any handle is enough to set them in the CURLSH object, because I can set them in one handle and read them any other handle.

How do I secure CFID for PCI compliance?

We've been failing our PCI scans because ColdFusion has predictable CFIDs. The exact FAIL we get is "Predictable Cookie Session IDs". Now the CFTOKEN is no longer predictable since I've configured CF to use UUID for CFTOKEN, however, the CFID is still predictable and unaffected by any changes in CF Admin.
I don't really know why the CFID being predictable is a threat, but they want us to fix it.
I have been unable to find anything on the matter by googeling, and I'm really not sure what else to do.
Has anyone else dealt with something like this? Any suggestions?
EDIT:Here is what my Application.cfc file looks like:
<cfcomponent output="false">
<cfset this.name="DatabaseOnline">
<cfset this.sessionManagement=true>
<cfset this.setDomainCookies=true>
<cfset this.setClientCookies=true>
<cfset this.sessionTimeOut=#CreateTimeSpan(0,20,0,0)#>
</cfcomponent>
And my CF admin looks like this: http://i.imgur.com/k9OZH.png
So how do I disable CFID?
Using J2EE session variables should address that problem.
To do that go to CF Administrator. Server Settings --> Memory Variables and check the 'Use J2EE session variables' check box.
You can find some more information here http://helpx.adobe.com/coldfusion/kb/predictable-cookie-session-ids-reported.html
Explain to the scanning agent that the CFID is sequential, but is not valid without a corresponding CFTOKEN cookie which is randomized. Since the session cannot be hijacked with the ID alone, it mitigates the reason for the scan failure. Their automated test assumes that the CFID cookie controls the session on its own, which is not the case. Every scanning vendor that I've worked with has accepted this as a mitigating factor and either disabled or overridden that specific test for me on CF-based sites.
Alternately, if none of the sites on the CF server use session variables, you can disable session management entirely and CF won't issue the cookies at all. If they are needed, the above explanation of how CF sessions are managed should get you through.

Cookie handling in subsequent requests in same page

I'm creating my own (multi threaded) ISAPI based website in C++ and I'm trying to implement correct session management.
The problem is that when a new session should be created, the session is created twice when using subsequent requests in the generated web page.
Here's how it works:
- Client requests http://localhost and sends either no cookie or a cookie with an old session ID in it.
- Server looks at the session cookie and feels that it needs to create a new one because it no longer exists: it prepares a header with a cookie in it with a new session ID and sends the complete header to the client (I tracked this with http live headers plugin in firefox and it is correct). It also prepares some data like the page and and stuff like that (not yet body data, as it is still processing data from the database and stuff like that) and sends what it has back to the client.
- Client should have this new session cookie now, and sees the stylesheet link and immediately sends the stylesheet request http://localhost/css to my server. But... he still does this with the old session ID for some reason, not with the newly received one!
- Server sees this request (with again an no longer existing session id), generates another new session and sends the new session id with a cookie along with the stylesheet data.
So the client has received two session id's now and will from now on keep using the second one as the first one is overwritten, but nevertheless the first page has used the wrong session (or actually, the second page has).
You could say that this is not a problem, but when I start using personalized stylesheets, I will have the wrong stylesheet on the first page and as the page will use AJAX to refresh the content (if available), it is possible that the stylesheet is never reloaded unless the client refreshes.
So, is this a problem that is always there when doing this kind of thing? Will the browser always send an old cookie although it has already received a new one but is still processing the page? Is this a problem that, for example PHP, also has?
Note: before all the discussions start about "use php instead" or something: I am rewriting a website that I had first written in PHP, it became popular, had thousands of (real) visitors every hour and started killing my server (the website doesn't make that kind of money that I can throw lots of servers at it). By writing it in C++, requests take 2ms instead of 200ms in PHP... I can optimize everything. By taking my time to develop this ISAPI correctly, it is safely multi-threaded and can be multi-processed, multi-servered. And most of all, I like the challenge.
Added note: It seems that the problem is only there when an old session exists in the cookies, because when I completely clear all cookies from my browser, and a new one is created and sent back to the client, the subsequent stylesheet request immediately uses the given session id. This seems to be some kind of proof that I'm doing something wrong when an old session id is sent... Should an existing cookie be deleted first? How?
Added note: The cookie is written with an expire-date one year ahead.
I have found out what the problem was, I was in the assumption that setting a cookie without specifying a path would result in making the session work on all paths on that domain.
By using http://foo.bar/home as main page and http://foo.bar/home/css as stylesheet, internally translating that url to ?s1=home and ?s1=home&css=y, I was actually using two different paths according to the browser which did not pass the cookie to the css-request.
For some reason, they actually got together afterwards, I don't fully understand why.
Isn't this silly? Will people not often have a http://foo.bar/index.php and a http://foo.bar/css/style.css.php , just because they use subdirectories to keep their structure clean?
If anyone knows of a way to fix it, to make subpaths also work with the same cookies, let me know, but as I understand it from the definition of cookies, they are stuck within a specific path (although, it seems that if you specifically add a path other than /, it will work on subdirectories as well?)