Bug 64921

Summary: LoadBalancerDrainingValve does not honour "Secure Session Cookie" settings
Product: Tomcat 9 Reporter: Andreas Kurth <apache>
Component: CatalinaAssignee: Tomcat Developers Mailing List <dev>
Status: RESOLVED FIXED    
Severity: normal    
Priority: P2    
Version: 9.0.39   
Target Milestone: -----   
Hardware: PC   
OS: Linux   

Description Andreas Kurth 2020-11-12 11:54:03 UTC
With Chrome browsers a redirection loop will be triggered when all of the following conditions apply:

* sameSiteCookies=none attribute has been set at the CookieProcessor
* LoadBalancerDrainingValve has been activated
* Site is called with timed out session

Reason: LoadBalancerDrainingValve tries to reset the JSESSIONID cookie. It adds "SameSite=None" as expected. But no matter what is configured for the "Secure Session Cookie" setting, it will never add the "Secure" attribute, too. Since Chrome does not accept "SameSite=None" without "Secure", it will reject the cookie, which will then be sent again and again in a redirection loop.
Comment 1 Christopher Schultz 2020-11-12 13:25:20 UTC
Hmm. It's not possible to know whether or not the browser thinks the cookie should be "secure" since the client doesn't send the "secure" flag to the server (it's a one-way flag, from server -> client).

Are you able to test a patch (or have you already developed one)?

Assuming the only thing missing is:

  sessionCookie.setSecure(true);

then we only have to worry about knowing when to set that flag. Modern systems should probably *always* set that flag, but someone out there surely needs is to NOT set the "secure" flag so we need a way to disable that. Probably via a configuration option "secure" which defaults to "true" but can be set to "false".
Comment 2 Andreas Kurth 2020-11-12 14:15:30 UTC
Setting "Secure" unconditionally would raise another issue: Chrome doesn't accept the Secure flag when not run under SSL. A possible – still naive – implementation might be:

if (request.isSecure()) {
    sessionCookie.setSecure(true);
}
Comment 3 Christopher Schultz 2020-11-12 16:01:41 UTC
Yes, I was thinking about some permutation of that.
Comment 4 Mark Thomas 2020-11-12 18:51:29 UTC
You should be able to do this in the Valve:
SessionCookieConfig scc = request.getContext().getServletContext().getSessionCookieConfig()

Then the logic used when the session cookie is created is:
sessionCookie.setSecure(request.isSecure() || scc.isSecure())

It should be possible to replicate that in the Valve.
Comment 5 Christopher Schultz 2020-11-13 18:48:27 UTC
That sounds good; I think there isn't any more configuration necessary, then since the Cookie configuration already has what it needs.

I love one-liner fixes.

Andreas, would you care to prepare a patch/PR for this?
Comment 6 Andreas Kurth 2020-11-14 07:38:40 UTC
https://github.com/apache/tomcat/pull/377

Windows smoke test failed due to an unrelated test failure.
Comment 7 Mark Thomas 2020-11-19 14:58:22 UTC
Fixed in:
- 10.0.x for 10.0.0-M11 onwards
- 9.0.x for 9.0.41 onwards
- 8.5.x for 8.5.61 onwards