Why does Tomcat return 400 status after updating to mitigate CVE-2016-6816?

Solution Verified - Updated

Environment

  • JBoss Web Server (JWS) 3.1
    • tomcat7
    • tomcat8
  • JBoss Enterprise Application Platform (EAP) 6.4.13+
  • Red Hat Enterprise Linux (RHEL) 6
    • tomcat6
  • Red Hat Enterprise Linux (RHEL) 7
    • tomcat

Issue

  • Tomcat returns a 400 status to my client after updating to mitigate CVE-2016-6816

Resolution

  • This is the intended behavior and there is no workaround currently (other than a downgrade) to revert the behavior to it's previous state. See the Root Cause section for more information.
  • A fix is available in JWS 3.1 SP1+ with Content from issues.jboss.org is not included.JWS-717 to allow '{', '}', or '|' characters to avoid 400s. Those characters can be allowed when specified through the tomcat.util.http.parser.HttpParser.requestTargetAllow system property:
tomcat.util.http.parser.HttpParser.requestTargetAllow="{|}"

Root Cause

The summary for CVE-2016-6816 is:

It was discovered that the code that parsed the HTTP request line permitted invalid characters. This could be exploited, in conjunction with a proxy that also permitted the invalid characters but with a different interpretation, to inject data into the HTTP response. By manipulating the HTTP response the attacker could poison a web-cache, perform an XSS attack and/or obtain sensitive information from requests other than their own.

The fix for CVE-2016-6816 enforces rules more strictly when handling invalid characters in HTTP requests.

As a result any clients making requests containing any of the following ASCII characters will receive a 400:

 1. Control characters (values 0x01 to 0x1f, and 0x7f)
 2. 8-bit ASCII values (values > 0x7f)
 3. Any of the following characters: 
  	' ' (space character)
  	'"' (double quote)
  	'#' (hash or pound)
  	'<' (less than)
  	'>' (greater than)
  	'\' (back slash)
  	'^' (circumflex)
  	'`' (backquote)
  	'{' (left squiggly bracket or brace)
  	'|' (vertical bar)
  	'}' (right squiggly bracket or brace)

The change does not affect encoded characters. If, for example, instead of using '|' in a request if '%7C' is used instead it will not result in a 400 status

Diagnostic Steps

  1. Update tomcat package to the version containing the fix

  2. Send a request which contains a curly braces ({ and }), or the pipe symbol (|), and you'll get "400 Bad Request" response

    $ curl -i localhost:8080/somepath/\|
    HTTP/1.1 400 Bad Request
    Server: Apache-Coyote/1.1
    Transfer-Encoding: chunked
    Date: Wed, 01 Feb 2017 15:50:37 GMT
    Connection: close
    
    
Components
Category

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.