Setting up HTTPOnly Session Cookies for ColdFusion

September 13, 2010
coldfusion

Internet Explorer pioneered a great security feature for cookies called HTTPOnly, when this flag is set the browser does not allow JavaScript to access the cookie. Now that all modern browsers support this flag it can reduce the risk of session hijacking due to cross site scripting. For that reason many security auditors will take marks off if you are not using it for your session identifier cookies (eg cfid, cftoken, and jsessionid).

I recently updated my ColdFusion Security Scanner, hackmycf.com to check for the omission of HTTPOnly session cookies. It now provides a warning if the cfid, cftoken, or jsessionid cookies do not set the HTTPOnly flag. We now also offer a subscription service which will scan your server automatically on a daily, weekly, monthly or quarterly basis.

ColdFusion 9 also introduced an attribute on the cfcookie tag called httponly which you can set to a boolean value. Prior to CF9 you can still create HTTPOnly cookies with ColdFusion but you have to use cfheader instead of cfcookie to write the cookies.

If running ColdFusion 10

ColdFusion 10 added a HTTPOnly setting to ColdFusion administrator under Server Settings » Memory Variables you can simply check the checkbox and you should be good.

You can also force this in your Application.cfc by specifying:

this.sessioncookie.httponly = true;

If running ColdFusion 9.0.1

ColdFusion 9.0.1 update added support by a java system property called coldfusion.sessioncookie.httponly you can turn this on by editing the jvm.config and adding the following to the java.args:

-Dcoldfusion.sessioncookie.httponly=true

If you are running Standalone (not multi-server/j2ee mode) you can add this in the ColdFusion Administrator

If Running CF 9.0 or greater

If you have not upgraded to 9.0.1 yet, or would rather solve this issue in your code, here’s an example Application.cfc file you could use:

<cfcomponent>
  <cfset this.sessionmanagement = true>
  <cfset this.setclientcookies = false>
  <cffunction name="onSessionStart">
      <cfcookie name="CFID" value="#session.cfid#" httponly="true">
      <cfcookie name="CFTOKEN" value="#session.cftoken#" httponly="true">
  </cffunction>
<cfcomponent>

If Running CF 8 or Lower and using Application.cfc

<cfcomponent>
  <cfset this.sessionmanagement = true>
  <cfset this.setclientcookies = false>
  <cffunction name="onSessionStart">
      <cfheader name="Set-Cookie" value="CFID=#session.CFID#;path=/;HTTPOnly">
      <cfheader name="Set-Cookie" value="CFTOKEN=#session.CFTOKEN#;path=/;HTTPOnly">
  </cffunction>
<cfcomponent>

Make sure you have setclientcookies = false specified.

If Using Application.cfm

If you are still using an Application.cfm file, you can use the following:

<cfapplication setclientcookies="false" sessionmanagement="true" name="test">
<cfif NOT IsDefined("cookie.cfid") OR NOT IsDefined("cookie.cftoken") OR cookie.cftoken IS NOT session.CFToken>
   <cfheader name="Set-Cookie" value="CFID=#session.CFID#;path=/;HTTPOnly">
   <cfheader name="Set-Cookie" value="CFTOKEN=#session.CFTOKEN#;path=/;HTTPOnly">
</cfif>

If using J2EE Session Cookies (jsessionid)

If you are using CF9.0.1 or greater use the java system property described above.

If you are using CF9.0 or lower, then you can edit the jrun-web.xml file located in WEB-INF as described here to enabled HTTPOnly cookies.

Jason Dean has also come up with a way to do this in onSessionStart as well.

Consider Setting The Secure Flag

If you have SSL, also consider setting the secure flag on your cookies. When the browser is given a cookie with the secure flag it only sends the cookie over a HTTPS connection.



Related Entries

This entry was:

Comments

A while ago I created a CF8-compatible function that attempts to recreate the functionality of cfcookie with the addition of httponly: http://www.modernsignal.com/coldfusionhttponlycookie
@David - Nice, thanks for sharing!
I am assuming that this means that making ajax requests will no longer pass data from cookies to authenticate. Isn't this a major problem for most all applications?

I have been relying on ajax passing on the CFID and token from the main session through async requests.

-Brian
@Brian - The HTTPOnly cookies will still be sent by the browser when making an ajax / XMLHttpRequest, the cookie values are just not accessible to the JavaScript code (But the browser has the values internally, and can still send them). So yes, you can still use ajax and maintain your session when using HTTPOnly cookies for CFID and CFTOKEN
Oh, excellent! Thanks for the great tip as always Pete.

-Brian
Very nice article! :)
When used with authentication, I'd previously assign a cookie and then immediately be able to validate it the same thread on the other included scripts. CFHeader doesn't assign the cookie to the ColdFusion "COOKIE" scope so it can't be accessed via by the server until the next subsequent web request. For this reason, I've found that it's safest/best to duplicate and re-scope (and test) cookie variables.
I am using CF8 and I have a need for the client scope, which we store in cookies. Your way 'setclientcookies=false' caused me a problem here. So I poked around a little and found this blog entry:

http://www.jeffryhouser.com/index.cfm/2010/11/10/Setting-HTTPOnly-and-Secure-for-the-ColdFusion-Session-cookies

And from this I derived this which seems to work well. Tell me if you see any issues with this and leaving 'setclientcookies=true'.

<cfset this.clientmanagement = true />
<cfset this.setclientcookies = true />

<cffunction name="onSessionStart" access="public" returntype="void" output="false">
<cfset var LOCAL = {} />

<cfset LOCAL.cookie = ";domain=" & cgi.http_host & ";path=/;HTTPOnly;" />

<cfif StructKeyExists(cgi, "https") and cgi.https is "on">
<cfset LOCAL.cookie &= "Secure;" />
</cfif>

<cfset LOCAL.cfidCookie = "cfid=" & session.cfid & LOCAL.cookie />
<cfset LOCAL.cftokenCookie = "cftoken=" & session.cftoken & LOCAL.cookie />

<cfcookie name="cfid" expires="now" />
<cfcookie name="cftoken" expires="now" />

<cfheader name="Set-Cookie" value="#LOCAL.cfidCookie#">
<cfheader name="Set-Cookie" value="#LOCAL.cftokenCookie#">
</cffunction>
@Daniel - I will have to do some research to confirm this, but it seams like what you are seeing is that if you are using onSessionStart then you don't need to specify setClientCookies=false

That may only be required if using Application.cfm
Does this setting change only affect the ColdFusion session cookies? Or does it affect all cookies that are created within the server? I think from reading your description it's only for the CF session cookies, but I want to be sure.
Thank you Pete! This helped me get this odd error fixed as I described in this small post.

http://blog.fusedevelopments.com/2011/03/coldfusion-9-hotfix-1-causes-session.html
Hello Pete.

I believe your suggestion for CF 9.0.1 is incorrect.

Your sussestion is that using -Dcoldfusion.sessioncookie.httponly=true will simply make jsessionid httponly.

However, what I believe it is doing is setting any session only cookies to httponly.

The main issue is the definition of seesioncookie. Instead of being "cookies that define the users session", I believe the real definition is "cookies that are set to expire at the end of the browser session"

So if you currently have code like "<cfset Cookie.ShowTab = 0>", and then have javascript that works with that cookie, then your code will break because the ShowTab cookie is httponly and not available to javascript.

Your described behaviour appears correct because jsessionid is a end-of-session cookie.

I beleive you shouldn't use coldfusion.sessioncookie.httponly unless you have reviewed the code for all sites on the server.

Possible workarounds are to always set a date expiry, or set the cookie in JS only and make the CF code allow for the cookie to not exist yet.

I haven't tested with cfcookie, but expect the same behaviour.

Hopefully CF10 will have httponly and secure settings for the jsessionid cookie as part of Application.cfc/cfapplication.
Pete,

At the end of this post you mention setting the "secure" flag on your cookies. Is that eluding to it being possible to set that as a JVM config argument as well or is this only available in the jrun-web.xml?
@Ted - There is no JVM argument for setting the secure flag. The setting to do that in jrun-web.xml only applies to J2EE (eg jsessionid) cookies and does not apply to CFID and CFTOKEN as far as I know. If you want secure cookies that are not jsessionid then you have to use cfcookie or cfheader to set them.
Thanks Pete, this and your previous post (regarding the jrun-web.xml updates) are both great, and very helpful.
@Grumpy Yes the setting only applies to session cookies and not cookies you create yourself (you can just add the httponly flag to cfcookie instead.

@Ted - Glad you found it useful.
@Pete I'm now running a system with hf901-00002.jar and I'm now getting the behaviour as you described it.

I'm not prepared to uninstall the patches to retest, but anyone reading this should disregard my previous comments if they are fully patched up.
@GrumpyCFer - Thanks for posting that update. Have a great day :)
I'm running session cookies on CF8 that loads under a subdomain with a site that uses an iFrame. When I configure as you've suggested, substituting the blank value of the path with the subdomain we're using, I'm running into problems where the page does not retain the session scope in IE. If I enable setclientcookies, I don't have this problem. Will configuring them this way pose a XSS security risk?
An inetllignet point of view, well expressed! Thanks!
An interesting side-effect of the HttpOnly session cookies might be -

Say you have this situation:
Your host puts you behind a load balancer. Communication between the browser and the load balancer is SSL, but betwene the load balancer and the coldfusion webserver is not.

Then, when you go to the https:// website, you will get HttpOnly session cookies (since the cf webserver can't tell that you're using https). If the browser respects the HttpOnly and throws those away, then you can't log in!

What do you think?
An interesting side-effect of the HttpOnly session cookies might be -

Say you have this situation:
Your host puts you behind a load balancer. Communication between the browser and the load balancer is SSL, but betwene the load balancer and the coldfusion webserver is not.

Then, when you go to the https:// website, you will get HttpOnly session cookies (since the cf webserver can't tell that you're using https). If the browser respects the HttpOnly and throws those away, then you can't log in!

What do you think?
Hi, Found that there's a bug in the CF8 code that affects IE browsers.

If you change it to <cfapplication setclientcookies="#false#" sessionmanagement="true" name="test">
It works.
Pgksrjgiohi hw hweokfjeq ojfe jfweiogwo gwoj wijf gdhgtrj575 y6u75tyhgf 5yu5regr
Ugireojfe whfiwehfjwehwhfjehfwefhweh 777uiop fweh iwehf weiohf wieohf iwehf iweyu59tu328hfire iuwfodhqw934785 h3urh9wjfwgut h9wh9889wh98r h4wt93qrj29th2 rj2ghw9tfq.
Xighefjeo orj wokwp dkow pwk wodj d hfdgfhgf 4756 5uhtyjur urt45

Post a Comment




  



Spell Checker by Foundeo

Recent Entries



foundeo


did you hack my cf?