Why does Tomcat return 400 status after updating to mitigate CVE-2016-6816?
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.requestTargetAllowsystem property:
tomcat.util.http.parser.HttpParser.requestTargetAllow="{|}"
- A request to allow unicode special characters has been filed for consideration with This content is not included.BZ-1459599 but it is denied
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
-
Update tomcat package to the version containing the fix
-
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
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.