Coldfusion Session Fixation - session

I need to reset the session identifier once user logs in to the application. But I have tried for several days, but still cannot reset jsessionid cookie and if it does, the server seems not recognize it. Could someone please provide some suggestion or some code examples?
Here is the code in login_action.cfm where login.cfm submit the form to:
login form submit user credential to login_action.cfm. here is the code in login_action.cfm:
<cfcookie name="JSESSIONID" value="0" expires="now">
<cfif IsDefined('cookie.JSESSIONID')>
<cfheader name="Set-Cookie" value="JSESSIONID=0;expires=#GetHttpTimeString(CreateODBCDateTime(now()))#;path=/;HTTPOnly;secure=true;">
</cfif>
<cfset structclear(session)>
<cfhttp url="loginverify.cfm" method="post" >
<cfhttpparam name="username" value="#form.username#" type="formfield" ><cfhttpparam name="password" value="#form.password#" type="formfield" >
</cfhttp>
<cfset cookieval = "#MID(cfhttp.responseheader['set-cookie'][1], 12, findnocase(";", cfhttp.responseheader['set-cookie'][1])-13)#">
<cfheader name="Set-Cookie" value="#cfhttp.responseheader['set-cookie'][1]#">
<cfset cookie.jsessionid = cookieval>
<cflocation url="myfirstpage.cfm" addtoken="no">
here is the code to authenticate the user in loginverify.cfm:
<!--- authenticate users --->
<!--- if user passed--->
<cfset session.gooduser = true>
<cfset session.userpermission = 1>
but it seems the session variables defined in loginverify.cfm is not recognized in login_action.cfm
.
Any suggestion?
Thanks a lot.

Just wanted to add an updated answer for this discussion. Since the last comments here, Adobe has addressed session fixation automatically within CF.
If you're on CF10, or if you install CF 9.0.2, that includes it.
If you are on 9.0.1 or less (back to 8.0) there is a security hotfix which add it: APSB11-04 (posted 2/8/2011 and updated 3/7/2011).
Note also that the technote for that fix ( http://helpx.adobe.com/coldfusion/kb/security-hotfix-coldfusion-8-8.html ) also mentions a workaround to disable the session fixation protection (and it would apply to those on 9.0.2 and 10 as well):
If you add the following JVM property, -Dcoldfusion.session.protectfixation=false, to the appropriate jvm.config for your CF instance (and restart), it will revert CF back to not adding the session fixation protection (which simply leaves your server as vulnerable to fixation attacks as it had always been).
Of course, most should want the protection, but as it does introduce some problems for some applications (not well-documented, sadly), just know that it is an option to turn it off, if needed.

An updated version of what you're trying to accomplish can be found at:
12Robots.com - Session token rotation REVISITED (wayback link)
However that has the issue of not cleaning up the extra sessions or carrying over any session data that you want to persist.
With session cleanup
You're not going to be able to log the user in and invalidate their session at the same time. You must invalidate their session and then in the next request, log them in. The basic flow would be something like:
Process login form and make sure the user is valid
Create a secure message containing the user credentials and session data to persist
Invalidate the session
Relocate the page to itself, with the secure message in the url
With the new session created for this page request, log the user in using the credentials from the secure message
Step 3 (invalidating the session) can be done as:
<cfscript>
session.setMaxInactiveInterval(1);
getPageContext().getSession().invalidate();
</cfscript>
<cfcookie name="jsessionid" expires="now">
<cfcookie name="cfid" expires="now">
<cfcookie name="cftoken" expires="now">
and then immediately redirect (cflocation) after that, making sure to have addtoken set to false.
You also need to make sure that the secure message is temporal and can't be used more than once. So you'll have additional database action on both sides of the redirect.
That will accomplish what you're after, but probably not as straight forward as you had hoped.
Simple alternate
Another method of preventing session fixation is to simply prevent step 2 in your reference from happening.
At the most simple, if you see jsessionid, cftoken or cfid in the url then cfabort the request. This must be done before the application "kicks in" and sets or processes client cookies. So in Application.cfm it would be done before cfapplication and in Application.cfc it would be done outside of any function (ie where you set "This.name").
You could take this further and strip out the session identifiers and cflocation to the safe url. This could also be done from the web server using mod_rewrite, et al, to stop ColdFusion from ever seeing the harmful url.
There are additional ways for that step 2 to happen, but all that come to mind require either your webserver or the users machine to be compromised, and if that's the case then session fixation is the least of either of your worries.

Related

In Railo, how do I delete a cookie?

I am using Railo - CFML and it seems that it is not using application.cfc/.cfm because I have deleted those from the folder and it worked just the same. With that being said.
I am trying to force cookies to be deleted when I someone logs out of my application. Some how the information is being restored after I have forced the information in the cookie to be changed.
I have physically deleted the cookie and it forces a CFID update. However, that's the only time that I have been able to get a CFID change. I have looked more into the cookie and using my web developer toolkit, the cookie is set to expire in 2045.
I have searched on here for hours looking for methods to work and I can tell you so far they work on other projects that I have worked on but for some reason I cannot get it to work on this current project. Just a heads up, I am the 15th programmer on this site.
Here is some of the code that I am working with:
<cfcookie
name="CFID"
value="Dead"
expires="NOW">
<cfcookie
name="cfid"
value="Dead"
expires="NOW">
<cfset structClear( session ) />
<cfset delete_cookie=StructDelete(cookie,"CFID")>
<cfcookie name="CFID" value="0" expires="Thu, 01-Jan-70 00:00:01 GMT">
<cfoutput>Cookie Deleted: #delete_cookie#<br /></cfoutput>
<cfset delete_cookie=StructDelete(cookie,"cfid")>
<cfcookie name="cfid" value="0"expires="Thu, 01-Jan-70 00:00:01 GMT">
<cfset delete_cookie_ga=StructDelete(cookie,"_ga")>
<cfcookie name="_ga" value="0"expires="Thu, 01-Jan-70 00:00:01 GMT">
<!--- Redirect back to index page. --->
<!----<cflocation
url="/"
addtoken="false"
/>--->
<cfdump var=#cookie#>
Here is what I am getting:
Before I use that code.
Scope
_ga string GA###########
cfid string (random letters & numbers)
cftoken string 50
After I use that code I get:
Scope
_ga string 0
cfid string 0
cftoken string 50
This is me trying 2 different ways to get the job done.
However, after I run this and look at my cookies for my site, I still see the CFID with an expiration of 2045.
Your code works fine for manipulating the cookie values on Railo. It appears Railo is performing session management tasks after the code has completed, and is setting the cfid cookies back.
Even if you could change the cfid cookie value, the existing session would still exist. Those that can view the session with the cfid in a url would still be able to use the corresponding session until it naturally times out. To invalidate a session in Railo 4 or higher you can use the SessionInvalidate() function. This function will update the clients cfid, and force the current session to expire.
Without knowing more about your application, I’m unsure if invalidating the session will resolve the security issues you have been working on.
After further research I have found that my Railo Server admin had the sessions to time out after 90 days. This has been changed and the sessions expire after 20 mins. So if you use railo make sure that you update web admin and not just server admin. Lesson learned. Thanks everyone. Also a HUGE thank you to Ben Nadel for helping with this problem!

Coldfusion 10 cross domain HTTPS session problems

Just wondering if anyone has come across an issue in CF10 whereby sessions are dropped when crossing between subdomains for the same Application under HTTPS, even though the JSESSIONID is being explicitly passed in these links which had worked for us for over 5 years without fail prior to CF10. From what I have read there appears to be a big change to address the Session Fixation security issues in CF10 which explains why the sessions would drop jumping between HTTP and HTTPS but this doesn't explain my issue. I understand the Session Fixation changes introduced in CF 9.02 and CF will definitely have an impact on our passing JSESSIONID via the URL, however this behaviour has been removed still the session is dropping.
Essentially we have CF10 installed with J2EE Session Management turned on, and the default HTTPOnly set to true. This is a single CF Application with the same Application name, setClientCookies is false and in the application the domain structure looks as follows:
https://book.domain.com
https://profile.domain.com
https://approve.domain.com
When crossing between the domains (which had worked for many years prior) the session drops and CF issues a new set of session identifiers.
Even setting a cookie in the onSessionStart() as follows has no effect:
<cfcookie name="jsessionid" value="#session.sessionid#" domain=".domain.com" secure="true">
Has anyone come across this behaviour migrating to CF10?
Cheers
Phil
So after playing around with a number of settings and ideas I now have the sessions behaving across the subdomains mentioned in my original question over HTTPS and using secure (browser based) cookies, thereby satisfying PCI-DSS Compliance requirements. All passing of JSESSIONID via the URL was removed from the system and the following lines added into the Application.cfc for both the constructors and the onSessionStart(). Note the setDomainCookies and setClientCookies set to false and the Domain specific sessioncookie settings below and also note in the onSessionStart my cookie being set without an expiry to ensure it only lasts for the duration of the browser, and the new CF10 encodeValue attribute to prevent strange encoding issues with the cookie values:
<cfcomponent hint="Application" output="false">
<cfscript>
// Application Settings
this.name = "myApplication";
this.applicationTimeout = createTimeSpan(0,2,0,0);
this.clientManagement = false;
this.loginStorage = "session";
this.sessionManagement = true;
this.sessionTimeout = createTimeSpan(0,1,0,0);
this.setClientCookies = false;
this.setDomainCookies = false;
// Domain specific settings for session persistence over subdomains
this.sessioncookie.domain = '.domain.com';
this.sessioncookie.httponly = true;
</cfscript>
<cffunction name="onSessionStart" returnType="void" output="false">
<cfcookie name="jsessionid" value="#session.sessionid#" secure="true" domain=".domain.com" encodeValue="false">
</cffunction>
</cfcomponent>

cakephp, session not working unless allow a cookie in browser

Using latest version of cakephp v2.3.3
I have a problem with my session variables when a browser doesn't allow cookies.
I pass variables from one controller to the other and this works perfect as long as the browser has cookies enabled. I have tried it with the Session helper in the controllers, but no effort, same problem.
How to fix this, is there a work around???
Cookies are required to keep track of the session ID, but you can manually get or set the session ID using $this->Session->id(). By adding the code below to the App Controllers' before filter you can set the session ID as a URL paramter like http://example.com/posts/view/1?session=qkv108c2pqeubcpeos1q7ekds3, for example.
if (!empty($this->request->query['session'])) {
$this->Session->id($this->request->query['session']);
}
The session ID is required for every request which means you have to include it in every link. I would suggest extending the HTML helpers' url and link methods to automatically add it.
Edit:
You should verify that $this->Session->read('Config.userAgent'); or $this->request->clientIp(); has not changed since the user was authenticated to prevent session hijacking. Thanks to thaJeztah for pointing this out.

what happens with session_start in global.asax if session timeouts?

I have multidomain web application which treats users differently based on URL they use.
I am using Session["data"] to keep information about user and starting this session with Session_Start["data"] in Global.asax.
All works fine but I would like to know what happens after inactivity. After certain time session will timeout. If that happens is Global.asax treating this as new user and will again start Session_Start for this user?
And will Session["data"] get updated with every page load/reload? Or because it starts just once and will timeout in some exact time?
I tried to make this question as clear as possible.
Thanks.
Session will renew/keep-alive everytime the server gets hit by that user.You set the timeout in the web config file and it is a sliding value, so it restarts again everytime there is a server request.
something like this:
<configuration>
<sessionstate
mode="inproc"
cookieless="false"
timeout="20" />
</configuration>
When the session times out, the next time there is a request, the Session_Start will execute. If you are accessing Session[data] from anywhere else in the code, you should check to make sure it is not null as it will throw a NullReferenceException if the session has timed out and you are trying to access it.
A new session starts when a user first visits a .NET URL (like an .aspx page, but not a .html or other static file) on your site. That session lasts until it times out or the application is killed (restarted/crashes/recycled). The default .NET timeout is 20 minutes; so a session will last as long as the user keeps hitting .aspx pages with no breaks longer than 20 minutes.
During that time, you can store information in the Session object that relates to that user. It is essentially a hashtable that you can populate with objects for which you define keys. In your case, you are using Session["data"], but you could use any key you want, really.
However a session, and the data you store in the Session hashtable, is very fragile (see all the ways it can die above). You shouldn't rely on it to keep anything important that can't be reconstructed easily (in Session_Start, for example). So it really serves two roles: maintaining state (so you know it is still the same user from page to page); and as a user-specific cache where you can keep data in memory to do things more quickly.
Session_Start just runs once per session--by definition. If you need to identify a single user over multiple sessions, you will need to use something more permanent like setting your own cookie with a far-future expiration. You can put an ID in such a cookie that lets you know this is user 12345 (in fact, Session_Start is just the place to look for your "permanent" cookie and connect your data about that existing user with this new session).
And if you want to store data about a user that survives multiple sessions, you will have to store that somewhere more permanent--a database being the most obvious solution. When they come back, you can cache some of that data in the Session hashtable--and Session_Start is just the place to do that as well. Hope this helps.
protected void Session_Start(object sender, EventArgs e)
{
// Code that runs when a new session is started
string RootURL = Request.ApplicationPath;
if (!RootURL.EndsWith("/"))
RootURL += "/";
Globals._rootURL = RootURL;
}

Manually start session with specific id / transitioning session cookie between domains

My host requires me to use a different domain for SSL secured access (shared SSL), so I need to transition the user session between two domains. One part of the page lives at http://example.com, while the SSL'd part is at https://example.hosting.com. As such I can't set a domain-spanning cookie.
What I'm trying to do is to transition the session id over and re-set the cookie like this:
http://example.com/normal/page, user clicks link to secure area and goes to:
http://example.com/secure/page, which causes a redirect to:
https://example.hosting.com/secure/page?sess=ikub..., which resurrects the session and sets a new cookie valid for the domain, then redirects to:
https://example.hosting.com/secure/page
This works up to the point where the session should be resurrected. I'm doing:
function beforeFilter() {
...
$this->Session->id($_GET['sess']);
$this->Session->activate();
...
}
As far as I can tell this should start the session with the given ID. It actually generates a new session ID though and this session is empty, the data is not restored.
This is on CakePHP 1.2.4. Do I need to do something else, or is there a better way to do what I'm trying to do?
When Configure::write('Security.level') is set to medium or higher, session.referer_check is implicitly activated, which makes the whole thing fail. Setting the security level to low (or using a custom session configuration) makes everything work as it should.
There went about 5 hours of debugging... ( -_-;;)
My first thought is to use the Cake file sessions and copy the file over, and then perhaps try and start a new session with that phpsessid, although I'm not even sure if that would actually work or not :)
With Cake 2.6.1 -- This is what worked for me.
$this->Session->id("tfvjv43hjmsnjkh0v3ss539uq7"); // add session id you want to set
$this->Session->id();
$this->Session->read("key"); // hhoorray worked :)
with SessionComponent id() function needs to be called twice once with session id to set session_id(); and second time to start cake session.
First call does not really start the session ... I dont know how Cake Guys missed it .....
Upvote if this works for you.

Resources