J2EE Sessions in CF10 Uses Secure Cookies
By Pete Freitag
This week I helped out a client resolve an issue due to a change in behavior from CF9 to CF10. CF10 automatically adds the secure flag to cookies when the request is over a secure HTTPS channel. CF9 and lower do not add the secure flag to your JSESSIONID cookies when the request is over HTTPS, you can set a flag to force it in all cases (by editing jrun-web.xml), but there is no way to do it conditionally.
It turns out this is a feature of Tomcat, not CF10
I did some digging in the Tomcat source code and found that this functionaility is hard coded into Tomcat, and there is no config to control it. If you are curious you can see the source code here: ApplicationSessionCookieConfig:141
// Always set secure if the request is secure if (scc.isSecure() || secure) { cookie.setSecure(true); }
This can lead to session loss, BUT it is also a good security feature
The secure flag on a cookie means that it will only send the cookie over a secure channel like HTTPS, so when a JSESSIONID cookie is set with a secure flag, it will not be sent on a HTTP request that is not HTTPS, so you have two sessions one for HTTPS and one for HTTP.
You can't securely share a session on both HTTP and HTTPS
While a lot of people want to share a session between http and https there is no way to do it in a secure way, once the JSESSIONID is sent over HTTP you have an opportunity for a man in the middle to snatch it.
A good way to solve this problem is to only use sessions on HTTPS, for any url that requires a session make sure it is over HTTPS. The best is to simply use HTTPS for everything.
For this particular customer it would take a major rewrite to accomodate all HTTPS or to switch away from J2EE sessions (note for CFID/CFTOKEN sessions you can controll the secure flag of the cookies in the Application.cfc using this.sessionconfig.secure=true/false). So they needed a workaround.
Here is a workaround (but know that it lessens the security of your sessions over https)
Keep in mind this workaround decreases security. So we need to remove the secure flag from the JSESSIONID cookie, and there is no easy way to do this in Tomcat or CFML that I'm aware of. So my solution was to rewrite the cookie in IIS using URL Rewrite, here's how you do this:
- Install Microsoft URL Rewrite for IIS: http://www.iis.net/downloads/microsoft/url-rewrite
- Close IIS, and open it again.
- Click On the root server level node of IIS (so that this is applicable to all sites on your server),
- Double Click on the URL Rewrite icon
- Click on Add Rule(s)
- Under Outbound Rules select Blank Rule
- Give it an arbitrary name, eg
RemoveSecureFlagOnJSESSIONID
- Under Match, select Matching Scope:
Server Variable
- For Variable name use:
RESPONSE_Set-Cookie
- Variable Value:
Matches Pattern
- Using:
Regular Expressions
- Pattern:
^(.*JSESSIONID.*)Secure;(.*)$
- Under Action, Action Type:
Rewrite
- Action Properties: Value:
{R:1}{R:2}
- Check replace existing server variable
Or here's how you can add it to a single site using web.config files:
<rewrite> <outboundRules> <rule name="RemoveSecureJessionID"> <match serverVariable="RESPONSE_Set-Cookie" pattern="^(.*JSESSIONID.*)Secure;(.*)$" /> <action type="Rewrite" value="{R:1}{R:2}" /> </rule> </outboundRules> </rewrite>
Note you can also use this technique to improve the security of JSESSIONID cookies on CF9 and lower by adding a HttpOnly flag or a secure flag to the cookie.
J2EE Sessions in CF10 Uses Secure Cookies was first published on April 05, 2013.
If you like reading about coldfusion, session, security, httponly, secure, cookie, jsessionid, or tomcat then you might also like:
- Setting up HTTPOnly Session Cookies for ColdFusion
- OpenSSL and ColdFusion / Lucee / Tomcat
- Scope Injection in CFML
- Session Loss and Session Fixation in ColdFusion
The Fixinator Code Security Scanner for ColdFusion & CFML is an easy to use security tool that every CF developer can use. It can also easily integrate into CI for automatic scanning on every commit.
Try Fixinator
CFBreak
The weekly newsletter for the CFML Community
Comments
It is a good security feature, but I was surprised that there is no config option to turn it off.
Thanks for sharing the workaround.
I would ask for just a couple of clarifications, if you don't mind.
First, you say in the opening paragraph that "CF10 automatically adds the secure flag to cookies when the request is over a secure HTTPS channel". Is that limited only to the session cookies (jsessionid or cfid/cftoken), or is that all cookies set from within CF? That might be interesting for some to know (if it is all cookies set in CF).
Similarly, you say "CF9 and lower do not add the secure flag to your JSESSIONID cookies when the request is over HTTPS, you can set a flag to force it in all cases, but there is no way to do it conditionally." Again, is that referring only to the session cookies( jsessionid and cfid/cftoken)? Or perhaps only to jsessionid (as you state)? or is it all cookies set from CF?
I see that you have the rule changing only the jsessionid cookie, and I do realize that the crux of the problem here is that with the impact on session cookies, that's causing the loss/confusion of sessions. So any other cookies would remain as created (with respect to the secure flag), given that rule, right? Is that because you feel it's best not to tamper with other cookies, and that for most users, there would not be confusion if the rest of their cookies (sent from CF) remained unchanged with respect to this?
Also, one might wonder whether the this.sessionconfig.secure=true/false (or the Admin setting) apply only to the older cfid/cftoken cookies and to JEE session cookies (jsessionid). It's not clear from here. Do you know?
(And Pete, would you agree that that app.cfc setting you showed is just the app-specific implementation of the new CF 10 Admin feature, on the "Memory Variables" page, in the section "Session Cookie Settings", as the "Secure Cookie" setting? That might be worth mentioning when you discuss that application.cfc setting, or you can leave this as the way some can connect that dot, if indeed they should. I bow to your expertise in this area.)
Finally, Shilpi, are those two settings (in app.cfc or the admin) SUPPOSED to be changing the processing of the session cookie, regardless of whether we are using JEE sessions or not? Someone reading this could think it applies only to cfid/cftoken. I'd hope, though, that it should apply to either kind of sessions.
I do realize that even if you intended that it should, it could not on Tomcat until there's a change in that hard-coded limitation that Pete's found.
Thanks to both of you for your participation in the discussion of this matter.
First this finding is only specific to the J2EE session cookie (I would call it jsessionid, but you can rename it in the config if you wanted to). It does not automatically add the secure flag to other cookies set with cfcookie, or otherwise, and it does not apply to CFID CFTOKEN session cookies.
When I was talking about setting session cookies on CF9/JRun - I was referring to j2ee / jsessionid cookie, you can make all jsessionid's have a secure flag by editing the jrun-web.xml file, see http://www.petefreitag.com/item/740.cfm but there is no way to do it conditionally.
I need to test and see if jsessionid can be controlled via this.sessionconfig in Application.cfc, I do know that the this.sessionconfig.secure does not matter on jsessionid, but I'm not sure about the other settings.
Hope that helps clarify some of this.
@Pete, as for your last comment, was that regarding CF10? If so, I would wonder if that might be only because of the Tomcat issue you've identified.
Still looking forward to Shilpi or someone at Adobe addressing the questions like that which I'd also raised yesterday.
Why will Tomcat give the following configuration when it will not honor it?
<cookie-config>
<secure>true/false</secure>