Apache Tomcat request smuggling via malformed content-length
Description
If Apache Tomcat 8.5.0 to 8.5.82, 9.0.0-M1 to 9.0.67, 10.0.0-M1 to 10.0.26 or 10.1.0-M1 to 10.1.0 was configured to ignore invalid HTTP headers via setting rejectIllegalHeader to false (the default for 8.5.x only), Tomcat did not reject a request containing an invalid Content-Length header making a request smuggling attack possible if Tomcat was located behind a reverse proxy that also failed to reject the request with the invalid header.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Apache Tomcat request smuggling vulnerability due to improper handling of invalid Content-Length headers when rejectIllegalHeader is false, enabling HTTP request smuggling behind a reverse proxy.
Vulnerability
Description
CVE-2022-42252 is an HTTP request smuggling vulnerability in Apache Tomcat. The root cause is that when the rejectIllegalHeader configuration option is set to false (the default for Tomcat 8.5.x), Tomcat does not reject HTTP requests containing an invalid Content-Length header. This allows an attacker to craft a request that is interpreted differently by Tomcat and a front-end reverse proxy, leading to request smuggling [1][2][3][4].
Exploitation
Conditions
To exploit this vulnerability, Tomcat must be configured with rejectIllegalHeader=false (the default for 8.5.x only; for 9.x and 10.x the default is true). Additionally, a reverse proxy positioned in front of Tomcat must also fail to reject the malformed Content-Length header. The attacker sends a specially crafted HTTP request with an invalid Content-Length value, causing parsing discrepancies between the proxy and Tomcat [4].
Impact
Successful exploitation allows an attacker to perform HTTP request smuggling. This can lead to cache poisoning, bypassing security controls, session hijacking, and other attacks that rely on the proxy and backend interpreting the request boundaries differently [4].
Mitigation
Apache has released fixed versions: Tomcat 8.5.83+, 9.0.68+, 10.0.27+, and 10.1.1+. Users should upgrade to these versions or set rejectIllegalHeader=true in the configuration. Note that Tomcat 8.5.x has reached end-of-life and users are encouraged to migrate to a supported branch [1][2][3].
AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.apache.tomcat.embed:tomcat-embed-coreMaven | >= 8.5.0, < 8.5.83 | 8.5.83 |
org.apache.tomcat.embed:tomcat-embed-coreMaven | >= 9.0.0-M1, < 9.0.68 | 9.0.68 |
org.apache.tomcat.embed:tomcat-embed-coreMaven | >= 10.0.0-M1, < 10.0.27 | 10.0.27 |
org.apache.tomcat.embed:tomcat-embed-coreMaven | >= 10.1.0-M1, < 10.1.1 | 10.1.1 |
org.apache.tomcat:tomcat-coyoteMaven | >= 9.0.0-M1, < 9.0.68 | 9.0.68 |
org.apache.tomcat:tomcat-coyoteMaven | >= 10.0.0-M1, < 10.0.27 | 10.0.27 |
org.apache.tomcat:tomcat-coyoteMaven | >= 10.1.0-M1, < 10.1.1 | 10.1.1 |
Affected products
26- osv-coords25 versionspkg:bitnami/tomcatpkg:maven/org.apache.tomcat.embed/tomcat-embed-corepkg:maven/org.apache.tomcat/tomcat-coyotepkg:rpm/opensuse/tomcat10&distro=openSUSE%20Tumbleweedpkg:rpm/opensuse/tomcat&distro=openSUSE%20Tumbleweedpkg:rpm/suse/tomcat&distro=SUSE%20Enterprise%20Storage%206pkg:rpm/suse/tomcat&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015%20SP1-ESPOSpkg:rpm/suse/tomcat&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015%20SP1-LTSSpkg:rpm/suse/tomcat&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015-ESPOSpkg:rpm/suse/tomcat&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015-LTSSpkg:rpm/suse/tomcat&distro=SUSE%20Linux%20Enterprise%20Server%2012%20SP2-BCLpkg:rpm/suse/tomcat&distro=SUSE%20Linux%20Enterprise%20Server%2012%20SP3-BCLpkg:rpm/suse/tomcat&distro=SUSE%20Linux%20Enterprise%20Server%2012%20SP4-LTSSpkg:rpm/suse/tomcat&distro=SUSE%20Linux%20Enterprise%20Server%2012%20SP5pkg:rpm/suse/tomcat&distro=SUSE%20Linux%20Enterprise%20Server%2012%20SP5-LTSSpkg:rpm/suse/tomcat&distro=SUSE%20Linux%20Enterprise%20Server%2015%20SP1-BCLpkg:rpm/suse/tomcat&distro=SUSE%20Linux%20Enterprise%20Server%2015%20SP1-LTSSpkg:rpm/suse/tomcat&distro=SUSE%20Linux%20Enterprise%20Server%2015-LTSSpkg:rpm/suse/tomcat&distro=SUSE%20Linux%20Enterprise%20Server%20for%20SAP%20Applications%2012%20SP4pkg:rpm/suse/tomcat&distro=SUSE%20Linux%20Enterprise%20Server%20for%20SAP%20Applications%2012%20SP5pkg:rpm/suse/tomcat&distro=SUSE%20Linux%20Enterprise%20Server%20for%20SAP%20Applications%2015pkg:rpm/suse/tomcat&distro=SUSE%20Linux%20Enterprise%20Server%20for%20SAP%20Applications%2015%20SP1pkg:rpm/suse/tomcat&distro=SUSE%20Linux%20Enterprise%20Server%20LTSS%20Extended%20Security%2012%20SP5pkg:rpm/suse/tomcat&distro=SUSE%20OpenStack%20Cloud%209pkg:rpm/suse/tomcat&distro=SUSE%20OpenStack%20Cloud%20Crowbar%209
>= 8.5.0, < 8.5.83+ 24 more
- (no CPE)range: >= 8.5.0, < 8.5.83
- (no CPE)range: >= 8.5.0, < 8.5.83
- (no CPE)range: >= 9.0.0-M1, < 9.0.68
- (no CPE)range: < 10.1.14-1.1
- (no CPE)range: < 9.0.43-11.1
- (no CPE)range: < 9.0.36-150100.4.81.1
- (no CPE)range: < 9.0.36-150100.4.81.1
- (no CPE)range: < 9.0.36-150100.4.81.1
- (no CPE)range: < 9.0.36-150000.3.101.2
- (no CPE)range: < 9.0.36-150000.3.101.2
- (no CPE)range: < 8.0.53-29.57.1
- (no CPE)range: < 8.0.53-29.57.1
- (no CPE)range: < 9.0.36-3.93.1
- (no CPE)range: < 9.0.36-3.93.1
- (no CPE)range: < 9.0.115-3.160.1
- (no CPE)range: < 9.0.36-150100.4.81.1
- (no CPE)range: < 9.0.36-150100.4.81.1
- (no CPE)range: < 9.0.36-150000.3.101.2
- (no CPE)range: < 9.0.36-3.93.1
- (no CPE)range: < 9.0.36-3.93.1
- (no CPE)range: < 9.0.36-150000.3.101.2
- (no CPE)range: < 9.0.36-150100.4.81.1
- (no CPE)range: < 9.0.115-3.160.1
- (no CPE)range: < 9.0.36-3.93.1
- (no CPE)range: < 9.0.36-3.93.1
- Apache Software Foundation/Apache Tomcatv5Range: 10.1.0-M1
Patches
4c9fe754e5d17Requests with invalid content-length should always be rejected
3 files changed · +65 −13
java/org/apache/coyote/http11/Http11InputBuffer.java+29 −13 modified@@ -919,7 +919,7 @@ private HeaderParseStatus parseHeader() throws IOException { headerData.lastSignificantChar = pos; byteBuffer.position(byteBuffer.position() - 1); // skipLine() will handle the error - return skipLine(); + return skipLine(false); } // chr is next byte of header name. Convert to lowercase. @@ -930,7 +930,7 @@ private HeaderParseStatus parseHeader() throws IOException { // Skip the line and ignore the header if (headerParsePos == HeaderParsePosition.HEADER_SKIPLINE) { - return skipLine(); + return skipLine(false); } // @@ -987,15 +987,11 @@ private HeaderParseStatus parseHeader() throws IOException { // CRLF or LF is an acceptable line terminator eol = true; } else if (prevChr == Constants.CR) { - // Invalid value - // Delete the header (it will be the most recent one) - headers.removeHeader(headers.size() - 1); - return skipLine(); + // Invalid value - also need to delete header + return skipLine(true); } else if (chr != Constants.HT && HttpParser.isControl(chr)) { - // Invalid value - // Delete the header (it will be the most recent one) - headers.removeHeader(headers.size() - 1); - return skipLine(); + // Invalid value - also need to delete header + return skipLine(true); } else if (chr == Constants.SP || chr == Constants.HT) { byteBuffer.put(headerData.realPos, chr); headerData.realPos++; @@ -1043,7 +1039,27 @@ private HeaderParseStatus parseHeader() throws IOException { } - private HeaderParseStatus skipLine() throws IOException { + private HeaderParseStatus skipLine(boolean deleteHeader) throws IOException { + boolean rejectThisHeader = rejectIllegalHeader; + // Check if rejectIllegalHeader is disabled and needs to be overridden + // for this header. The header name is required to determine if this + // override is required. The header name is only available once the + // header has been created. If the header has been created then + // deleteHeader will be true. + if (!rejectThisHeader && deleteHeader) { + if (headers.getName(headers.size() - 1).equalsIgnoreCase("content-length")) { + // Malformed content-length headers must always be rejected + // RFC 9112, section 6.3, bullet 5. + rejectThisHeader = true; + } else { + // Only need to delete the header if the request isn't going to + // be rejected (it will be the most recent one) + headers.removeHeader(headers.size() - 1); + } + } + + // Parse the rest of the invalid header so we can construct a useful + // exception and/or debug message. headerParsePos = HeaderParsePosition.HEADER_SKIPLINE; boolean eol = false; @@ -1069,11 +1085,11 @@ private HeaderParseStatus skipLine() throws IOException { headerData.lastSignificantChar = pos; } } - if (rejectIllegalHeader || log.isDebugEnabled()) { + if (rejectThisHeader || log.isDebugEnabled()) { String message = sm.getString("iib.invalidheader", HeaderUtil.toPrintableString(byteBuffer.array(), headerData.lineStart, headerData.lastSignificantChar - headerData.lineStart + 1)); - if (rejectIllegalHeader) { + if (rejectThisHeader) { throw new IllegalArgumentException(message); } log.debug(message);
test/org/apache/coyote/http11/TestHttp11InputBuffer.java+31 −0 modified@@ -709,6 +709,37 @@ public void testInvalidHeader01() { } + @Test + public void testInvalidContentLength01() { + doTestInvalidContentLength(false); + } + + + @Test + public void testInvalidContentLength02() { + doTestInvalidContentLength(true); + } + + + private void doTestInvalidContentLength(boolean rejectIllegalHeader) { + getTomcatInstance().getConnector().setProperty("rejectIllegalHeader", Boolean.toString(rejectIllegalHeader)); + + String[] request = new String[1]; + request[0] = + "POST /test HTTP/1.1" + CRLF + + "Host: localhost:8080" + CRLF + + "Content-Length: 12\u000734" + CRLF + + "Connection: close" + CRLF + + CRLF; + + InvalidClient client = new InvalidClient(request); + + client.doRequest(); + Assert.assertTrue(client.getResponseLine(), client.isResponse400()); + Assert.assertTrue(client.isResponseBodyOK()); + } + + /** * Invalid request test client. */
webapps/docs/changelog.xml+5 −0 modified@@ -124,6 +124,11 @@ <bug>66281</bug>: Fix unexpected timeouts that may appear as client disconnections when using HTTP/2 and NIO2. (markt) </fix> + <fix> + Enforce the requirement of RFC 7230 onwards that a request with a + malformed <code>content-length</code> header should always be rejected + with a 400 response. (markt) + </fix> </changelog> </subsection> <subsection name="Jasper">
a1c07906d8dcRequests with invalid content-length should always be rejected
3 files changed · +65 −13
java/org/apache/coyote/http11/Http11InputBuffer.java+29 −13 modified@@ -919,7 +919,7 @@ private HeaderParseStatus parseHeader() throws IOException { headerData.lastSignificantChar = pos; byteBuffer.position(byteBuffer.position() - 1); // skipLine() will handle the error - return skipLine(); + return skipLine(false); } // chr is next byte of header name. Convert to lowercase. @@ -930,7 +930,7 @@ private HeaderParseStatus parseHeader() throws IOException { // Skip the line and ignore the header if (headerParsePos == HeaderParsePosition.HEADER_SKIPLINE) { - return skipLine(); + return skipLine(false); } // @@ -987,15 +987,11 @@ private HeaderParseStatus parseHeader() throws IOException { // CRLF or LF is an acceptable line terminator eol = true; } else if (prevChr == Constants.CR) { - // Invalid value - // Delete the header (it will be the most recent one) - headers.removeHeader(headers.size() - 1); - return skipLine(); + // Invalid value - also need to delete header + return skipLine(true); } else if (chr != Constants.HT && HttpParser.isControl(chr)) { - // Invalid value - // Delete the header (it will be the most recent one) - headers.removeHeader(headers.size() - 1); - return skipLine(); + // Invalid value - also need to delete header + return skipLine(true); } else if (chr == Constants.SP || chr == Constants.HT) { byteBuffer.put(headerData.realPos, chr); headerData.realPos++; @@ -1043,7 +1039,27 @@ private HeaderParseStatus parseHeader() throws IOException { } - private HeaderParseStatus skipLine() throws IOException { + private HeaderParseStatus skipLine(boolean deleteHeader) throws IOException { + boolean rejectThisHeader = rejectIllegalHeader; + // Check if rejectIllegalHeader is disabled and needs to be overridden + // for this header. The header name is required to determine if this + // override is required. The header name is only available once the + // header has been created. If the header has been created then + // deleteHeader will be true. + if (!rejectThisHeader && deleteHeader) { + if (headers.getName(headers.size() - 1).equalsIgnoreCase("content-length")) { + // Malformed content-length headers must always be rejected + // RFC 9112, section 6.3, bullet 5. + rejectThisHeader = true; + } else { + // Only need to delete the header if the request isn't going to + // be rejected (it will be the most recent one) + headers.removeHeader(headers.size() - 1); + } + } + + // Parse the rest of the invalid header so we can construct a useful + // exception and/or debug message. headerParsePos = HeaderParsePosition.HEADER_SKIPLINE; boolean eol = false; @@ -1069,11 +1085,11 @@ private HeaderParseStatus skipLine() throws IOException { headerData.lastSignificantChar = pos; } } - if (rejectIllegalHeader || log.isDebugEnabled()) { + if (rejectThisHeader || log.isDebugEnabled()) { String message = sm.getString("iib.invalidheader", HeaderUtil.toPrintableString(byteBuffer.array(), headerData.lineStart, headerData.lastSignificantChar - headerData.lineStart + 1)); - if (rejectIllegalHeader) { + if (rejectThisHeader) { throw new IllegalArgumentException(message); } log.debug(message);
test/org/apache/coyote/http11/TestHttp11InputBuffer.java+31 −0 modified@@ -709,6 +709,37 @@ public void testInvalidHeader01() { } + @Test + public void testInvalidContentLength01() { + doTestInvalidContentLength(false); + } + + + @Test + public void testInvalidContentLength02() { + doTestInvalidContentLength(true); + } + + + private void doTestInvalidContentLength(boolean rejectIllegalHeader) { + getTomcatInstance().getConnector().setProperty("rejectIllegalHeader", Boolean.toString(rejectIllegalHeader)); + + String[] request = new String[1]; + request[0] = + "POST /test HTTP/1.1" + CRLF + + "Host: localhost:8080" + CRLF + + "Content-Length: 12\u000734" + CRLF + + "Connection: close" + CRLF + + CRLF; + + InvalidClient client = new InvalidClient(request); + + client.doRequest(); + Assert.assertTrue(client.getResponseLine(), client.isResponse400()); + Assert.assertTrue(client.isResponseBodyOK()); + } + + /** * Invalid request test client. */
webapps/docs/changelog.xml+5 −0 modified@@ -195,6 +195,11 @@ <bug>66281</bug>: Fix unexpected timeouts that may appear as client disconnections when using HTTP/2 and NIO2. (markt) </fix> + <fix> + Enforce the requirement of RFC 7230 onwards that a request with a + malformed <code>content-length</code> header should always be rejected + with a 400 response. (markt) + </fix> </changelog> </subsection> <subsection name="Jasper">
4c7f4fd09d2cRequests with invalid content-length should always be rejected
3 files changed · +65 −13
java/org/apache/coyote/http11/Http11InputBuffer.java+29 −13 modified@@ -919,7 +919,7 @@ private HeaderParseStatus parseHeader() throws IOException { headerData.lastSignificantChar = pos; byteBuffer.position(byteBuffer.position() - 1); // skipLine() will handle the error - return skipLine(); + return skipLine(false); } // chr is next byte of header name. Convert to lowercase. @@ -930,7 +930,7 @@ private HeaderParseStatus parseHeader() throws IOException { // Skip the line and ignore the header if (headerParsePos == HeaderParsePosition.HEADER_SKIPLINE) { - return skipLine(); + return skipLine(false); } // @@ -987,15 +987,11 @@ private HeaderParseStatus parseHeader() throws IOException { // CRLF or LF is an acceptable line terminator eol = true; } else if (prevChr == Constants.CR) { - // Invalid value - // Delete the header (it will be the most recent one) - headers.removeHeader(headers.size() - 1); - return skipLine(); + // Invalid value - also need to delete header + return skipLine(true); } else if (chr != Constants.HT && HttpParser.isControl(chr)) { - // Invalid value - // Delete the header (it will be the most recent one) - headers.removeHeader(headers.size() - 1); - return skipLine(); + // Invalid value - also need to delete header + return skipLine(true); } else if (chr == Constants.SP || chr == Constants.HT) { byteBuffer.put(headerData.realPos, chr); headerData.realPos++; @@ -1043,7 +1039,27 @@ private HeaderParseStatus parseHeader() throws IOException { } - private HeaderParseStatus skipLine() throws IOException { + private HeaderParseStatus skipLine(boolean deleteHeader) throws IOException { + boolean rejectThisHeader = rejectIllegalHeader; + // Check if rejectIllegalHeader is disabled and needs to be overridden + // for this header. The header name is required to determine if this + // override is required. The header name is only available once the + // header has been created. If the header has been created then + // deleteHeader will be true. + if (!rejectThisHeader && deleteHeader) { + if (headers.getName(headers.size() - 1).equalsIgnoreCase("content-length")) { + // Malformed content-length headers must always be rejected + // RFC 9112, section 6.3, bullet 5. + rejectThisHeader = true; + } else { + // Only need to delete the header if the request isn't going to + // be rejected (it will be the most recent one) + headers.removeHeader(headers.size() - 1); + } + } + + // Parse the rest of the invalid header so we can construct a useful + // exception and/or debug message. headerParsePos = HeaderParsePosition.HEADER_SKIPLINE; boolean eol = false; @@ -1069,11 +1085,11 @@ private HeaderParseStatus skipLine() throws IOException { headerData.lastSignificantChar = pos; } } - if (rejectIllegalHeader || log.isDebugEnabled()) { + if (rejectThisHeader || log.isDebugEnabled()) { String message = sm.getString("iib.invalidheader", HeaderUtil.toPrintableString(byteBuffer.array(), headerData.lineStart, headerData.lastSignificantChar - headerData.lineStart + 1)); - if (rejectIllegalHeader) { + if (rejectThisHeader) { throw new IllegalArgumentException(message); } log.debug(message);
test/org/apache/coyote/http11/TestHttp11InputBuffer.java+31 −0 modified@@ -709,6 +709,37 @@ public void testInvalidHeader01() { } + @Test + public void testInvalidContentLength01() { + doTestInvalidContentLength(false); + } + + + @Test + public void testInvalidContentLength02() { + doTestInvalidContentLength(true); + } + + + private void doTestInvalidContentLength(boolean rejectIllegalHeader) { + getTomcatInstance().getConnector().setProperty("rejectIllegalHeader", Boolean.toString(rejectIllegalHeader)); + + String[] request = new String[1]; + request[0] = + "POST /test HTTP/1.1" + CRLF + + "Host: localhost:8080" + CRLF + + "Content-Length: 12\u000734" + CRLF + + "Connection: close" + CRLF + + CRLF; + + InvalidClient client = new InvalidClient(request); + + client.doRequest(); + Assert.assertTrue(client.getResponseLine(), client.isResponse400()); + Assert.assertTrue(client.isResponseBodyOK()); + } + + /** * Invalid request test client. */
webapps/docs/changelog.xml+5 −0 modified@@ -124,6 +124,11 @@ <bug>66281</bug>: Fix unexpected timeouts that may appear as client disconnections when using HTTP/2 and NIO2. (markt) </fix> + <fix> + Enforce the requirement of RFC 7230 onwards that a request with a + malformed <code>content-length</code> header should always be rejected + with a 400 response. (markt) + </fix> </changelog> </subsection> <subsection name="Jasper">
0d089a15047fRequests with invalid content-length should always be rejected
3 files changed · +65 −13
java/org/apache/coyote/http11/Http11InputBuffer.java+29 −13 modified@@ -919,7 +919,7 @@ private HeaderParseStatus parseHeader() throws IOException { headerData.lastSignificantChar = pos; byteBuffer.position(byteBuffer.position() - 1); // skipLine() will handle the error - return skipLine(); + return skipLine(false); } // chr is next byte of header name. Convert to lowercase. @@ -930,7 +930,7 @@ private HeaderParseStatus parseHeader() throws IOException { // Skip the line and ignore the header if (headerParsePos == HeaderParsePosition.HEADER_SKIPLINE) { - return skipLine(); + return skipLine(false); } // @@ -987,15 +987,11 @@ private HeaderParseStatus parseHeader() throws IOException { // CRLF or LF is an acceptable line terminator eol = true; } else if (prevChr == Constants.CR) { - // Invalid value - // Delete the header (it will be the most recent one) - headers.removeHeader(headers.size() - 1); - return skipLine(); + // Invalid value - also need to delete header + return skipLine(true); } else if (chr != Constants.HT && HttpParser.isControl(chr)) { - // Invalid value - // Delete the header (it will be the most recent one) - headers.removeHeader(headers.size() - 1); - return skipLine(); + // Invalid value - also need to delete header + return skipLine(true); } else if (chr == Constants.SP || chr == Constants.HT) { byteBuffer.put(headerData.realPos, chr); headerData.realPos++; @@ -1043,7 +1039,27 @@ private HeaderParseStatus parseHeader() throws IOException { } - private HeaderParseStatus skipLine() throws IOException { + private HeaderParseStatus skipLine(boolean deleteHeader) throws IOException { + boolean rejectThisHeader = rejectIllegalHeader; + // Check if rejectIllegalHeader is disabled and needs to be overridden + // for this header. The header name is required to determine if this + // override is required. The header name is only available once the + // header has been created. If the header has been created then + // deleteHeader will be true. + if (!rejectThisHeader && deleteHeader) { + if (headers.getName(headers.size() - 1).equalsIgnoreCase("content-length")) { + // Malformed content-length headers must always be rejected + // RFC 9112, section 6.3, bullet 5. + rejectThisHeader = true; + } else { + // Only need to delete the header if the request isn't going to + // be rejected (it will be the most recent one) + headers.removeHeader(headers.size() - 1); + } + } + + // Parse the rest of the invalid header so we can construct a useful + // exception and/or debug message. headerParsePos = HeaderParsePosition.HEADER_SKIPLINE; boolean eol = false; @@ -1069,11 +1085,11 @@ private HeaderParseStatus skipLine() throws IOException { headerData.lastSignificantChar = pos; } } - if (rejectIllegalHeader || log.isDebugEnabled()) { + if (rejectThisHeader || log.isDebugEnabled()) { String message = sm.getString("iib.invalidheader", HeaderUtil.toPrintableString(byteBuffer.array(), headerData.lineStart, headerData.lastSignificantChar - headerData.lineStart + 1)); - if (rejectIllegalHeader) { + if (rejectThisHeader) { throw new IllegalArgumentException(message); } log.debug(message);
test/org/apache/coyote/http11/TestHttp11InputBuffer.java+31 −0 modified@@ -709,6 +709,37 @@ public void testInvalidHeader01() { } + @Test + public void testInvalidContentLength01() { + doTestInvalidContentLength(false); + } + + + @Test + public void testInvalidContentLength02() { + doTestInvalidContentLength(true); + } + + + private void doTestInvalidContentLength(boolean rejectIllegalHeader) { + getTomcatInstance().getConnector().setProperty("rejectIllegalHeader", Boolean.toString(rejectIllegalHeader)); + + String[] request = new String[1]; + request[0] = + "POST /test HTTP/1.1" + CRLF + + "Host: localhost:8080" + CRLF + + "Content-Length: 12\u000734" + CRLF + + "Connection: close" + CRLF + + CRLF; + + InvalidClient client = new InvalidClient(request); + + client.doRequest(); + Assert.assertTrue(client.getResponseLine(), client.isResponse400()); + Assert.assertTrue(client.isResponseBodyOK()); + } + + /** * Invalid request test client. */
webapps/docs/changelog.xml+5 −0 modified@@ -124,6 +124,11 @@ <bug>66281</bug>: Fix unexpected timeouts that may appear as client disconnections when using HTTP/2 and NIO2. (markt) </fix> + <fix> + Enforce the requirement of RFC 7230 onwards that a request with a + malformed <code>content-length</code> header should always be rejected + with a 400 response. (markt) + </fix> </changelog> </subsection> <subsection name="Jasper">
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
11- github.com/advisories/GHSA-p22x-g9px-3945ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2022-42252ghsaADVISORY
- github.com/apache/tomcat/commit/0d089a15047faf9cb3c82f80f4d28febd4798920ghsaWEB
- github.com/apache/tomcat/commit/4c7f4fd09d2cc1692112ef70b8ee23a7a037ae77ghsaWEB
- github.com/apache/tomcat/commit/a1c07906d8dcaf7957e5cc97f5cdbac7d18a205aghsaWEB
- github.com/apache/tomcat/commit/c9fe754e5d17e262dfbd3eab2a03ca96ff372dc3ghsaWEB
- lists.apache.org/thread/zzcxzvqfdqn515zfs3dxb7n8gty589sqghsaWEB
- security.gentoo.org/glsa/202305-37ghsaWEB
- tomcat.apache.org/security-10.htmlghsaWEB
- tomcat.apache.org/security-8.htmlghsaWEB
- tomcat.apache.org/security-9.htmlghsaWEB
News mentions
0No linked articles in our index yet.