Pete Freitag Pete Freitag

J2EE Sessions in CF10 Uses Secure Cookies

Updated on December 07, 2023
By Pete Freitag
coldfusion

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:

  1. Install Microsoft URL Rewrite for IIS: http://www.iis.net/downloads/microsoft/url-rewrite
  2. Close IIS, and open it again.
  3. Click On the root server level node of IIS (so that this is applicable to all sites on your server),
  4. Double Click on the URL Rewrite icon
  5. Click on Add Rule(s)
  6. Under Outbound Rules select Blank Rule
  7. Give it an arbitrary name, eg RemoveSecureFlagOnJSESSIONID
  8. Under Match, select Matching Scope: Server Variable
  9. For Variable name use: RESPONSE_Set-Cookie
  10. Variable Value: Matches Pattern
  11. Using: Regular Expressions
  12. Pattern: ^(.*JSESSIONID.*)Secure;(.*)$
  13. Under Action, Action Type: Rewrite
  14. Action Properties: Value: {R:1}{R:2}
  15. 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.



coldfusion session security httponly secure cookie jsessionid tomcat

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:

Fixinator

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

Hi Pete,

Why will Tomcat give the following configuration when it will not honor it?
<cookie-config>
<secure>true/false</secure>
by Shilpi on 04/05/2013 at 12:57:34 PM UTC
Hi Shilpi, Good question -- it appears that setting secure=false has no effect, but setting secure=true does have an effect. Would be a good question to ask if you guys have some friends on the Tomcat core team.

It is a good security feature, but I was surprised that there is no config option to turn it off.
by Pete Freitag on 04/05/2013 at 1:03:10 PM UTC
hmmmmm i would be interested in knowing the reasoning behind it. Let's see what i get.

Thanks for sharing the workaround.
by Shilpi on 04/05/2013 at 1:05:37 PM UTC
Really great work there, Pete, both the understanding of the problem, and the available solutions (and workaround). Thanks for sharing it.

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.
by Charlie Arehart on 04/09/2013 at 5:18:26 PM UTC
@Richard - If anything this finding is pro for using J2EE sessions from a security perspective, but you can also accomplish the same using CFID/CFTOKEN by conditionally setting the this.sessionconfig.secure=cgi.https IS "on" in your Application.cfc in CF10.
by Pete Freitag on 04/09/2013 at 8:26:59 PM UTC
@Charlie, great questions - I'll try to answer them all here and also update the blog entry:

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.
by Pete Freitag on 04/09/2013 at 8:34:07 PM UTC
@Richard - I did some quick testing and it appears that the CF admin settings, and the Application.cfc this.sessionconfig settings do not apply to JSESSIONID, they are only for CFID CFTOKEN sessions.
by Pete Freitag on 04/10/2013 at 2:42:16 PM UTC
Thanks, Pete, for your response to my questions (and Richard, for your kind regards to them).

@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.
by Charlie Arehart on 04/10/2013 at 2:58:50 PM UTC
@Charlie - Yes my last comment was in reference to CF10 because the settings this.sessionconfig (and corresponding CF admin settings) were introduced in CF10.
by Pete Freitag on 04/10/2013 at 3:08:01 PM UTC
The settings added in CF10 are for ColdFusion session cookies ( CFID/CFTOKEN/CFAUTHORIZATION). JSESSIONID settings are configured at server level in web.xml.
by Shilpi on 04/15/2013 at 1:09:25 AM UTC
Your interesting URLrewrite discovery may inform a solution to a problem that is vexing me right now: apparently, the SetDomainCookies setting does not apply to jsessionid, therefore not allowing cross-subdomain J2EE sessions. When an *additional* jsessionid cookie is written (without subdomain) it doesn't help, because the subdomain-specific cookie rules. Do you think URLrewrite could be used to write the jsessionid cookie *uniquely* to be a domain cookie without subdomain?
by DonCx on 12/15/2015 at 4:11:22 PM UTC