Setting up HTTPOnly Session Cookies for ColdFusion

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 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 -Dcoldfusion.sessioncookie.httponly=true or if you are running Standalone 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:

 Download FuseGuard WAF for ColdFusion

Trackbacks

Trackback Address: 764/1404C649CAA38F6A6A52498FA030722E

Comments

On 09/13/2010 at 12:35:17 PM EDT David Hammond wrote:
1
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

On 09/13/2010 at 12:38:56 PM EDT Pete Freitag wrote:
2
@David - Nice, thanks for sharing!

On 09/15/2010 at 1:43:41 AM EDT Brian wrote:
3
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

On 09/15/2010 at 12:35:06 PM EDT Pete Freitag wrote:
4
@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

On 09/15/2010 at 12:51:18 PM EDT Brian wrote:
5
Oh, excellent! Thanks for the great tip as always Pete.

-Brian

On 09/15/2010 at 2:00:42 PM EDT John Farrar wrote:
6
Very nice article! :)

On 09/29/2010 at 6:47:34 PM EDT James Moberg wrote:
7
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.

On 11/29/2010 at 6:41:25 PM EST Daniel Budde wrote:
8
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>

On 11/29/2010 at 7:34:05 PM EST Pete Freitag wrote:
9
@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

On 12/21/2010 at 2:33:04 PM EST Jake Munson wrote:
10
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.

On 03/15/2011 at 10:45:31 PM EDT Giancarlo Gomez wrote:
11
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

On 03/31/2011 at 10:45:17 AM EDT Grumpy CFer wrote:
12
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.

On 06/27/2011 at 2:44:30 PM EDT tedsteinmann wrote:
13
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?

On 06/27/2011 at 2:51:45 PM EDT Pete Freitag wrote:
14
@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.

On 06/27/2011 at 2:54:45 PM EDT tedsteinmann wrote:
15
Thanks Pete, this and your previous post (regarding the jrun-web.xml updates) are both great, and very helpful.

On 06/27/2011 at 3:06:04 PM EDT Pete Freitag wrote:
16
@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.

On 07/01/2011 at 8:05:55 AM EDT Grumpy CFer wrote:
17
@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.

On 07/01/2011 at 12:04:47 PM EDT Pete Freitag wrote:
18
@GrumpyCFer - Thanks for posting that update. Have a great day :)

On 10/18/2011 at 12:28:16 PM EDT Kevin wrote:
19
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?

On 12/17/2011 at 11:12:16 AM EST Keydren wrote:
20
An inetllignet point of view, well expressed! Thanks!

Post a Comment




  



Spell Checker by Foundeo

Recent Entries



foundeo


did you hack my cf?