Bug 57872

Summary: Do not auto-switch session cookie to version=1 due to '/' in Path when running in "strict compliance" mode (Internet Explorer and rfc6265)
Product: Tomcat 8 Reporter: Konstantin Kolinko <knst.kolinko>
Component: CatalinaAssignee: Tomcat Developers Mailing List <dev>
Status: NEW ---    
Severity: enhancement    
Priority: P2    
Version: 8.5.x-trunk   
Target Milestone: ----   
Hardware: PC   
OS: All   

Description Konstantin Kolinko 2015-04-29 07:49:07 UTC
Encountered this when migrating a legacy web application from old Tomcat 6 to current Tomcat 7(.0.61). Reproducible with current Tomcat 8 as well.
Essential is that both Tomcat 6 and Tomcat 7 were configured with

org.apache.catalina.STRICT_SERVLET_COMPLIANCE=true

User-visible symptoms:

The count of active sessions (as shown in Manager application) increases rapidly. This does not occur when the same application is deployed on Tomcat 6.

Debugging:

1) Configured AccessLogValve to log incoming "cookie" headers and outgoing "set-cookie" headers and the current session.Id by adding the following text to its pattern:

SessionId:%S [Cookie received: %{cookie}i] [Set-Cookie sent: %{set-cookie}o]

2) Disabled HttpOnly -- to bring Tomcat 7 configuration more closely to Tomcat 6 one. This is done by setting <Context useHttpOnly="false"> in context file of the web application.


Cause:

In year 2009 a new feature was implemented in Tomcat 7 that a cookie is automatically switched from "version 0" cookie (Netscape cookie) to "version 1" cookie (RFC2109 cookie) when value/path/domain properties of the cookie contain a character that need to be quoted.

When "STRICT_SERVLET_COMPLIANCE" is true, one of characters that triggers "version 1" is '/'. As every session cookie contains a Path that starts with '/' this causes all session cookies to become "version 1" ones.


The problem is when client is Internet Explorer.

If I look into access log, the set-cookie header sent by an old Tomcat 6 looks like the following:

JSESSIONID=E8776ACC0C787BBAD5C7EEC4770877E1; Path=/foo

The set-cookie header sent by Tomcat 7 looks like the following:

JSESSIONID=A7A0CBBF5813DF4DEADFFFD3475E09AD; Version=1; Path="/foo/"

The problem is quoted value of Path. It is not understood by Internet Explorer and subsequent HTTP and Ajax requests do not include a "cookie" header. This is observed both with IE 8 and with current IE 11.

For a reference, an old report


Known solution:

Tomcat 7 and 8: Set the following system property:
org.apache.tomcat.util.http.ServerCookie.FWD_SLASH_IS_SEPARATOR=false

Tomcat 8 (better solution): configure a <CookieProcessor> to be "org.apache.tomcat.util.http.Rfc6265CookieProcessor" instead of default LegacyCookieProcessor.

See
http://tomcat.apache.org/tomcat-8.0-doc/config/cookie-processor.html


Proposal:
1) '/' alone should not trigger conversion from version 0 cookie to version 1 cookie. Netscape specification (as linked from rfc6265) uses unquoted '/' in Path in its examples, so it is explicitly OK to use '/' in the Path.

Generally, there may be other safe characters, as RFC6265 allows <any CHAR except CTLs or ";"> in path-value, but '/' is such a blatant example. Every path starts with a '/'.

2) Processing of a cookie that has "version=1" (set explicitly, or converted due to other reasons) is unchanged. The path will be quoted here. RFC2109 quotes Path in its examples.

The FWD_SLASH_IS_SEPARATOR flag is left to control quoting in version 1 cookies. (This is why I do not propose changing the default value of FWD_SLASH_IS_SEPARATOR).
Comment 1 Konstantin Kolinko 2015-04-29 08:16:33 UTC
> For a reference, an old report

I meant to link to bug 45272 there. Just for information.
Comment 2 Mark Thomas 2021-05-05 11:33:14 UTC
With Tomcat 7 reaching EOL, move the remaining open enhancement requests to Tomcat 8.