File tomcat-8.0.53-CVE-2022-42252.patch of Package tomcat.32132
From 4c7f4fd09d2cc1692112ef70b8ee23a7a037ae77 Mon Sep 17 00:00:00 2001
From: Mark Thomas <markt@apache.org>
Date: Mon, 3 Oct 2022 11:59:01 +0100
Subject: [PATCH] Requests with invalid content-length should always be
rejected
---
From 4c7f4fd09d2cc1692112ef70b8ee23a7a037ae77 Mon Sep 17 00:00:00 2001
From: Mark Thomas <markt@apache.org>
Date: Mon, 3 Oct 2022 11:59:01 +0100
Subject: [PATCH] Requests with invalid content-length should always be
rejected
---
Index: apache-tomcat-8.0.53-src/java/org/apache/coyote/http11/AbstractNioInputBuffer.java
===================================================================
--- apache-tomcat-8.0.53-src.orig/java/org/apache/coyote/http11/AbstractNioInputBuffer.java
+++ apache-tomcat-8.0.53-src/java/org/apache/coyote/http11/AbstractNioInputBuffer.java
@@ -493,8 +493,8 @@ public abstract class AbstractNioInputBu
// Non-token characters are illegal in header names
// Parsing continues so the error can be reported in context
headerData.lastSignificantChar = pos;
- // skipLine() will handle the error
- return skipLine();
+ // skipLine(true) will handle the error
+ return skipLine(true);
}
// chr is next byte of header name. Convert to lowercase.
@@ -506,7 +506,7 @@ public abstract class AbstractNioInputBu
// Skip the line and ignore the header
if (headerParsePos == HeaderParsePosition.HEADER_SKIPLINE) {
- return skipLine();
+ return skipLine(true);
}
//
@@ -561,12 +561,12 @@ public abstract class AbstractNioInputBu
// Invalid value
// Delete the header (it will be the most recent one)
headers.removeHeader(headers.size() - 1);
- return skipLine();
+ 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();
+ return skipLine(true);
} else if (chr == Constants.SP || chr == Constants.HT) {
buf[headerData.realPos] = chr;
headerData.realPos++;
@@ -619,7 +619,22 @@ public abstract class AbstractNioInputBu
return parsingRequestLinePhase;
}
- private HeaderParseStatus skipLine() throws IOException {
+ private HeaderParseStatus skipLine(boolean deleteHeader) throws IOException {
+ boolean rejectThisHeader = false;
+ if (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;
@@ -649,11 +664,11 @@ public abstract class AbstractNioInputBu
pos++;
}
- if (rejectIllegalHeaderName || getLog().isDebugEnabled()) {
+ if (rejectThisHeader || getLog().isDebugEnabled()) {
String message = sm.getString("iib.invalidheader", new String(buf, headerData.start,
headerData.lastSignificantChar - headerData.start + 1,
StandardCharsets.ISO_8859_1));
- if (rejectIllegalHeaderName) {
+ if (rejectThisHeader) {
throw new IllegalArgumentException(message);
}
getLog().debug(message);
Index: apache-tomcat-8.0.53-src/test/org/apache/coyote/http11/TestAbstractHttp11Processor.java
===================================================================
--- apache-tomcat-8.0.53-src.orig/test/org/apache/coyote/http11/TestAbstractHttp11Processor.java
+++ apache-tomcat-8.0.53-src/test/org/apache/coyote/http11/TestAbstractHttp11Processor.java
@@ -977,3 +977,33 @@ public class TestAbstractHttp11Processor
}
}
}
+
+ @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());
+ }
Index: apache-tomcat-8.0.53-src/webapps/docs/changelog.xml
===================================================================
--- apache-tomcat-8.0.53-src.orig/webapps/docs/changelog.xml
+++ apache-tomcat-8.0.53-src/webapps/docs/changelog.xml
@@ -5593,6 +5593,11 @@
under low load for a socket queued to be added to the Poller not to be
added for 10 seconds. (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">