Pete Freitag Pete Freitag

Setting up HTTPOnly Session Cookies for ColdFusion

Updated on December 07, 2023
By Pete Freitag
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 or Above

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.

Setting The Secure Flag

If your site runs over HTTPS, you should also be 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. Add the following to your Application.cfc and update the ColdFusion Administrator settings:

this.sessioncookie.secure = true;

The above will take care of the CFID and CFTOKEN cookies, if you also have a JSESSIONID cookie then you need make sure this cookie has the secure flag too. In most cases this is taken care of automatically by the J2EE server (eg Tomcat), but if not then you may need to do something like this on the Web Server to add the Secure flag to the cookie.



httponly cookies session cfid cftoken jsessionid security

Setting up HTTPOnly Session Cookies for ColdFusion was first published on September 13, 2010.

If you like reading about httponly, cookies, session, cfid, cftoken, jsessionid, or security then you might also like:

FuseGuard Web App Firewall for ColdFusion

The FuseGuard Web Application Firewall for ColdFusion & CFML is a high performance, customizable engine that blocks various attacks against your ColdFusion applications.

CFBreak
The weekly newsletter for the CFML Community


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
by David Hammond on 09/13/2010 at 10:35:17 AM UTC
@David - Nice, thanks for sharing!
by Pete Freitag on 09/13/2010 at 10:38:56 AM UTC
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
by Brian on 09/14/2010 at 11:43:41 PM UTC
@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
by Pete Freitag on 09/15/2010 at 10:35:06 AM UTC
Oh, excellent! Thanks for the great tip as always Pete.

-Brian
by Brian on 09/15/2010 at 10:51:18 AM UTC
Very nice article! :)
by John Farrar on 09/15/2010 at 12:00:42 PM UTC
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.
by James Moberg on 09/29/2010 at 4:47:34 PM UTC
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>
by Daniel Budde on 11/29/2010 at 4:41:25 PM UTC
@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
by Pete Freitag on 11/29/2010 at 5:34:05 PM UTC
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.
by Jake Munson on 12/21/2010 at 12:33:04 PM UTC
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
by Giancarlo Gomez on 03/15/2011 at 8:45:31 PM UTC
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.
by Grumpy CFer on 03/31/2011 at 8:45:17 AM UTC
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?
by tedsteinmann on 06/27/2011 at 12:44:30 PM UTC
@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.
by Pete Freitag on 06/27/2011 at 12:51:45 PM UTC
Thanks Pete, this and your previous post (regarding the jrun-web.xml updates) are both great, and very helpful.
by tedsteinmann on 06/27/2011 at 12:54:45 PM UTC
@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.
by Pete Freitag on 06/27/2011 at 1:06:04 PM UTC
@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.
by Grumpy CFer on 07/01/2011 at 6:05:55 AM UTC
@GrumpyCFer - Thanks for posting that update. Have a great day :)
by Pete Freitag on 07/01/2011 at 10:04:47 AM UTC
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?
by Kevin on 10/18/2011 at 10:28:16 AM UTC