Possible issues with cookies after upgrading to Tomcat 8

From: http://www.lichenliang.top/tomcat-8-invalid-character-cookie-value.html

problem scenario

For the web project running in Tomcat 7 before, when Tomcat is upgraded from 7 to 8.x and later, the user login fails and an exception is reported in the background:

java.lang.IllegalArgumentException: An invalid character [xx] was present in the Cookie value
 at org.apache.tomcat.util.http.Rfc6265CookieProcessor.validateCookieValue(Rfc6265CookieProcessor.java:162)
 at org.apache.tomcat.util.http.Rfc6265CookieProcessor.generateHeader(Rfc6265CookieProcessor.java:111)
 ...

norm change

Tomcat 8.x (or later) has made many improvements, and the cookie handling has also been upgraded to the RFC6265 specification, which may cause web projects that run without problems in Tomcat 8 to report the following error in Tomcat 8:

java.lang.IllegalArgumentException: An invalid character [34] was present in the Cookie value

The 34 in [34] above refers to the character " (double quotation marks) corresponding to the ASCII code (decimal). Then when the characters available for the cookie value in the RFC6265 specification are not clearly known, other characters may also appear in the cookie value. The problem.

So let's take a look at which characters are not available.

View source code

private void validateCookieValue(String value) {
    int start = 0;
    int end = value.length();

    if (end > 1 && value.charAt(0) == '"' && value.charAt(end - 1) == '"') {
        start = 1;
        end--;
    }

    char[] chars = value.toCharArray();
    for (int i = start; i < end; i++) {
        char c = chars[i];
        if (c < 0x21 || c == 0x22 || c == 0x2c || c == 0x3b || c == 0x5c || c == 0x7f) {
            throw new IllegalArgumentException(sm.getString(
                    "rfc6265CookieProcessor.invalidCharInValue", Integer.toString(c)));
        }
    }
}

Rfc6265CookieProcessor.validateCookieValue source address

Through the above source code analysis, the strings that are not available for cookie values ​​in the RFC6265 specification are analyzed, as shown in the following table:

decimal hex Abbreviation/Character explain
34 0x22 Double quotes
44 0x2C , comma
59 0x3B ; semicolon
92 0x5C \ backslash
127 0x7f DEL (delete) delete (control character)
< 33 < 0x21 slightly Control characters/communication special characters/space

problem causes

Tomcat 8 replaces the default CookieProcessor implementation with Rfc6265CookieProcessor, and the previous implementation is LegacyCookieProcessor. The former is based on RFC6265, while the latter is based on RFC6265, RFC2109, and RFC2616.

Solution

Standalone Tomcat

Modify the configuration file context.xml and specify the CookieProcessor as org.apache.tomcat.util.http.LegacyCookieProcessor. The specific configuration is as follows:

<Context>
    <CookieProcessor className="org.apache.tomcat.util.http.LegacyCookieProcessor" />
</Context>

SpringBoot embedded Tomcat solution

Add the configuration bean embedded with Tomcat in the springboot startup class, as follows:

@SpringBootApplication
public class Application extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    // Tomcat cookie handling configuration bean
    @Bean
    public WebServerFactoryCustomizer<TomcatServletWebServerFactory> cookieProcessorCustomizer() {
        return (factory) -> factory.addContextCustomizers(
            (context) -> context.setCookieProcessor(new LegacyCookieProcessor()));
    }
}

References:

Tomcat 8 CookieProcessor implementation changes
Baidu Encyclopedia ASCII

Related Posts