Fix CVE-2021-33037

This commit is contained in:
wang_yue111 2021-07-19 11:46:07 +08:00
parent 7de80b3fed
commit 4684794918
4 changed files with 385 additions and 1 deletions

160
CVE-2021-33037-1.patch Normal file
View File

@ -0,0 +1,160 @@
From 94a5f7b95adee95fbc945767a71c27e329970a80 Mon Sep 17 00:00:00 2001
From: Mark Thomas <markt@apache.org>
Date: Mon, 10 May 2021 21:20:46 +0100
Subject: [PATCH] Remove support for the identity T-E header value
---
.../apache/coyote/http11/Http11Processor.java | 7 +-
.../coyote/http11/TestHttp11Processor.java | 95 ++++++++++++++-----
webapps/docs/changelog.xml | 6 ++
3 files changed, 78 insertions(+), 30 deletions(-)
diff --git a/java/org/apache/coyote/http11/Http11Processor.java b/java/org/apache/coyote/http11/Http11Processor.java
index 86556ec..c840c83 100644
--- a/java/org/apache/coyote/http11/Http11Processor.java
+++ b/java/org/apache/coyote/http11/Http11Processor.java
@@ -243,11 +243,8 @@ public class Http11Processor extends AbstractProcessor {
// encoding names are case insensitive. (RFC2616, section 3.6)
encodingName = encodingName.trim().toLowerCase(Locale.ENGLISH);
- if (encodingName.equals("identity")) {
- // Skip
- } else if (encodingName.equals("chunked")) {
- inputBuffer.addActiveFilter
- (inputFilters[Constants.CHUNKED_FILTER]);
+ if (encodingName.equals("chunked")) {
+ inputBuffer.addActiveFilter(inputFilters[Constants.CHUNKED_FILTER]);
contentDelimitation = true;
} else {
for (int i = pluggableFilterIndex; i < inputFilters.length; i++) {
diff --git a/test/org/apache/coyote/http11/TestHttp11Processor.java b/test/org/apache/coyote/http11/TestHttp11Processor.java
index 5357526..1d12007 100644
--- a/test/org/apache/coyote/http11/TestHttp11Processor.java
+++ b/test/org/apache/coyote/http11/TestHttp11Processor.java
@@ -249,31 +249,6 @@ public class TestHttp11Processor extends TomcatBaseTest {
}
- @Test
- public void testWithTEIdentity() throws Exception {
- getTomcatInstanceTestWebapp(false, true);
-
- String request =
- "POST /test/echo-params.jsp HTTP/1.1" + SimpleHttpClient.CRLF +
- "Host: any" + SimpleHttpClient.CRLF +
- "Transfer-encoding: identity" + SimpleHttpClient.CRLF +
- "Content-Length: 9" + SimpleHttpClient.CRLF +
- "Content-Type: application/x-www-form-urlencoded" +
- SimpleHttpClient.CRLF +
- "Connection: close" + SimpleHttpClient.CRLF +
- SimpleHttpClient.CRLF +
- "test=data";
-
- Client client = new Client(getPort());
- client.setRequest(new String[] {request});
-
- client.connect();
- client.processRequest();
- Assert.assertTrue(client.isResponse200());
- Assert.assertTrue(client.getResponseBody().contains("test - data"));
- }
-
-
@Test
public void testWithTESavedRequest() throws Exception {
getTomcatInstanceTestWebapp(false, true);
@@ -1308,4 +1283,74 @@ public class TestHttp11Processor extends TomcatBaseTest {
// Expected response is a 200 response.
Assert.assertTrue(client.isResponse200());
}
+
+
+ @Test
+ public void testTEHeaderUnknown01() throws Exception {
+ doTestTEHeaderUnknown("identity");
+ }
+
+
+ @Test
+ public void testTEHeaderUnknown02() throws Exception {
+ doTestTEHeaderUnknown("identity, chunked");
+ }
+
+
+ @Test
+ public void testTEHeaderUnknown03() throws Exception {
+ doTestTEHeaderUnknown("unknown, chunked");
+ }
+
+
+ @Test
+ public void testTEHeaderUnknown04() throws Exception {
+ doTestTEHeaderUnknown("void");
+ }
+
+
+ @Test
+ public void testTEHeaderUnknown05() throws Exception {
+ doTestTEHeaderUnknown("void, chunked");
+ }
+
+
+ @Test
+ public void testTEHeaderUnknown06() throws Exception {
+ doTestTEHeaderUnknown("void, identity");
+ }
+
+
+ @Test
+ public void testTEHeaderUnknown07() throws Exception {
+ doTestTEHeaderUnknown("identity, void");
+ }
+
+
+ private void doTestTEHeaderUnknown(String headerValue) throws Exception {
+ Tomcat tomcat = getTomcatInstance();
+
+ // No file system docBase required
+ Context ctx = tomcat.addContext("", null);
+
+ // Add servlet
+ Tomcat.addServlet(ctx, "TesterServlet", new TesterServlet(false));
+ ctx.addServletMappingDecoded("/foo", "TesterServlet");
+
+ tomcat.start();
+
+ String request =
+ "GET /foo HTTP/1.1" + SimpleHttpClient.CRLF +
+ "Host: localhost:" + getPort() + SimpleHttpClient.CRLF +
+ "Transfer-Encoding: " + headerValue + SimpleHttpClient.CRLF +
+ SimpleHttpClient.CRLF;
+
+ Client client = new Client(tomcat.getConnector().getLocalPort());
+ client.setRequest(new String[] {request});
+
+ client.connect();
+ client.processRequest(false);
+
+ Assert.assertTrue(client.isResponse501());
+ }
}
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index bc37288..94a0d94 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -309,6 +309,12 @@
Enable host name verification when using TLS with the WebSocket client.
(markt)
</fix>
+ <fix>
+ Remove support for the <code>identity</code> transfer encoding. The
+ inclusion of this encoding in RFC 2616 was an error that was corrected
+ in 2001. Requests using this transfer encoding will now receive a 501
+ response. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Web applications">
--
2.23.0

81
CVE-2021-33037-2.patch Normal file
View File

@ -0,0 +1,81 @@
From 66bd71277cedd04af2772942c697e15d5c401de9 Mon Sep 17 00:00:00 2001
From: Mark Thomas <markt@apache.org>
Date: Mon, 10 May 2021 21:59:44 +0100
Subject: [PATCH] Process T-E header from both HTTP 1.0 and HTTP 1.1.clients
---
.../apache/coyote/http11/Http11Processor.java | 4 ++-
.../coyote/http11/TestHttp11Processor.java | 28 +++++++++++++++++++
webapps/docs/changelog.xml | 4 +++
3 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/java/org/apache/coyote/http11/Http11Processor.java b/java/org/apache/coyote/http11/Http11Processor.java
index c840c83..4021355 100644
--- a/java/org/apache/coyote/http11/Http11Processor.java
+++ b/java/org/apache/coyote/http11/Http11Processor.java
@@ -766,7 +766,9 @@ public class Http11Processor extends AbstractProcessor {
InputFilter[] inputFilters = inputBuffer.getFilters();
// Parse transfer-encoding header
- if (http11) {
+ // HTTP specs say an HTTP 1.1 server should accept any recognised
+ // HTTP 1.x header from a 1.x client unless the specs says otherwise.
+ if (!http09) {
MessageBytes transferEncodingValueMB = headers.getValue("transfer-encoding");
if (transferEncodingValueMB != null) {
String transferEncodingValue = transferEncodingValueMB.toString();
diff --git a/test/org/apache/coyote/http11/TestHttp11Processor.java b/test/org/apache/coyote/http11/TestHttp11Processor.java
index 1d12007..84fdd42 100644
--- a/test/org/apache/coyote/http11/TestHttp11Processor.java
+++ b/test/org/apache/coyote/http11/TestHttp11Processor.java
@@ -1353,4 +1353,32 @@ public class TestHttp11Processor extends TomcatBaseTest {
Assert.assertTrue(client.isResponse501());
}
+
+
+ @Test
+ public void testWithTEChunkedHttp10() throws Exception {
+
+ getTomcatInstanceTestWebapp(false, true);
+
+ String request =
+ "POST /test/echo-params.jsp HTTP/1.0" + SimpleHttpClient.CRLF +
+ "Host: any" + SimpleHttpClient.CRLF +
+ "Transfer-encoding: chunked" + SimpleHttpClient.CRLF +
+ "Content-Type: application/x-www-form-urlencoded" +
+ SimpleHttpClient.CRLF +
+ "Connection: close" + SimpleHttpClient.CRLF +
+ SimpleHttpClient.CRLF +
+ "9" + SimpleHttpClient.CRLF +
+ "test=data" + SimpleHttpClient.CRLF +
+ "0" + SimpleHttpClient.CRLF +
+ SimpleHttpClient.CRLF;
+
+ Client client = new Client(getPort());
+ client.setRequest(new String[] {request});
+
+ client.connect();
+ client.processRequest();
+ Assert.assertTrue(client.isResponse200());
+ Assert.assertTrue(client.getResponseBody().contains("test - data"));
+ }
}
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 94a0d94..e47f3d6 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -315,6 +315,10 @@
in 2001. Requests using this transfer encoding will now receive a 501
response. (markt)
</fix>
+ <fix>
+ Process transfer encoding headers from both HTTP 1.0 and HTTP 1.1
+ clients. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Web applications">
--
2.23.0

137
CVE-2021-33037-3.patch Normal file
View File

@ -0,0 +1,137 @@
From 74888576a60ec58ee99454e4202a0eb1a7720d98 Mon Sep 17 00:00:00 2001
From: Mark Thomas <markt@apache.org>
Date: Mon, 10 May 2021 22:14:18 +0100
Subject: [PATCH] Ensure chunked, if present, is the last encoding in the list
---
.../apache/coyote/http11/Http11Processor.java | 13 ++++++++-
.../coyote/http11/TestHttp11Processor.java | 28 +++++++++++++------
webapps/docs/changelog.xml | 5 ++++
3 files changed, 36 insertions(+), 10 deletions(-)
diff --git a/java/org/apache/coyote/http11/Http11Processor.java b/java/org/apache/coyote/http11/Http11Processor.java
index 4021355..17932b9 100644
--- a/java/org/apache/coyote/http11/Http11Processor.java
+++ b/java/org/apache/coyote/http11/Http11Processor.java
@@ -238,11 +238,22 @@ public class Http11Processor extends AbstractProcessor {
* supported, a 501 response will be returned to the client.
*/
private void addInputFilter(InputFilter[] inputFilters, String encodingName) {
+ if (contentDelimitation) {
+ // Chunked has already been specified and it must be the final
+ // encoding.
+ // 400 - Bad request
+ response.setStatus(400);
+ setErrorState(ErrorState.CLOSE_CLEAN, null);
+ if (log.isDebugEnabled()) {
+ log.debug(sm.getString("http11processor.request.prepare") +
+ " Tranfer encoding lists chunked before [" + encodingName + "]");
+ }
+ return;
+ }
// Trim provided encoding name and convert to lower case since transfer
// encoding names are case insensitive. (RFC2616, section 3.6)
encodingName = encodingName.trim().toLowerCase(Locale.ENGLISH);
-
if (encodingName.equals("chunked")) {
inputBuffer.addActiveFilter(inputFilters[Constants.CHUNKED_FILTER]);
contentDelimitation = true;
diff --git a/test/org/apache/coyote/http11/TestHttp11Processor.java b/test/org/apache/coyote/http11/TestHttp11Processor.java
index 84fdd42..ceb2601 100644
--- a/test/org/apache/coyote/http11/TestHttp11Processor.java
+++ b/test/org/apache/coyote/http11/TestHttp11Processor.java
@@ -1287,47 +1287,53 @@ public class TestHttp11Processor extends TomcatBaseTest {
@Test
public void testTEHeaderUnknown01() throws Exception {
- doTestTEHeaderUnknown("identity");
+ doTestTEHeaderInvalid("identity", false);
}
@Test
public void testTEHeaderUnknown02() throws Exception {
- doTestTEHeaderUnknown("identity, chunked");
+ doTestTEHeaderInvalid("identity, chunked", false);
}
@Test
public void testTEHeaderUnknown03() throws Exception {
- doTestTEHeaderUnknown("unknown, chunked");
+ doTestTEHeaderInvalid("unknown, chunked", false);
}
@Test
public void testTEHeaderUnknown04() throws Exception {
- doTestTEHeaderUnknown("void");
+ doTestTEHeaderInvalid("void", false);
}
@Test
public void testTEHeaderUnknown05() throws Exception {
- doTestTEHeaderUnknown("void, chunked");
+ doTestTEHeaderInvalid("void, chunked", false);
}
@Test
public void testTEHeaderUnknown06() throws Exception {
- doTestTEHeaderUnknown("void, identity");
+ doTestTEHeaderInvalid("void, identity", false);
}
@Test
public void testTEHeaderUnknown07() throws Exception {
- doTestTEHeaderUnknown("identity, void");
+ doTestTEHeaderInvalid("identity, void", false);
}
- private void doTestTEHeaderUnknown(String headerValue) throws Exception {
+ @Test
+ public void testTEHeaderChunkedNotLast01() throws Exception {
+ doTestTEHeaderInvalid("chunked, void", true);
+ }
+
+
+ private void doTestTEHeaderInvalid(String headerValue, boolean badRequest) throws Exception {
Tomcat tomcat = getTomcatInstance();
// No file system docBase required
@@ -1351,7 +1357,11 @@ public class TestHttp11Processor extends TomcatBaseTest {
client.connect();
client.processRequest(false);
- Assert.assertTrue(client.isResponse501());
+ if (badRequest) {
+ Assert.assertTrue(client.isResponse400());
+ } else {
+ Assert.assertTrue(client.isResponse501());
+ }
}
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index e47f3d6..35b8eab 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -319,6 +319,11 @@
Process transfer encoding headers from both HTTP 1.0 and HTTP 1.1
clients. (markt)
</fix>
+ <fix>
+ Ensure that if the transfer encoding header contains the
+ <code>chunked</code>, that the <code>chunked</code> encoding is the
+ final encoding listed. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Web applications">
--
2.23.0

View File

@ -13,7 +13,7 @@
Name: tomcat
Epoch: 1
Version: %{major_version}.%{minor_version}.%{micro_version}
Release: 18
Release: 19
Summary: Implementation of the Java Servlet, JavaServer Pages, Java Expression Language and Java WebSocket technologies
License: ASL 2.0
URL: http://tomcat.apache.org/
@ -82,6 +82,9 @@ Patch6037: CVE-2021-25329-pre1.patch
Patch6038: CVE-2021-25329-pre2.patch
Patch6039: CVE-2021-25329-pre3.patch
Patch6040: CVE-2021-25329.patch
Patch6041: CVE-2021-33037-1.patch
Patch6042: CVE-2021-33037-2.patch
Patch6043: CVE-2021-33037-3.patch
BuildRequires: ecj >= 1:4.6.1 findutils apache-commons-collections apache-commons-daemon
BuildRequires: apache-commons-dbcp apache-commons-pool tomcat-taglibs-standard ant
@ -483,6 +486,9 @@ fi
%{_javadocdir}/%{name}
%changelog
* Mon Jul 19 2021 wangyue <wangyue92@huawei.com> - 1:9.0.10-19
- Fix CVE-2021-33037
* Fri Mar 12 2021 wangyue <wangyue92@huawei.com> - 1:9.0.10-18
- Type:cve
- ID: CVE-2021-25122 CVE-2021-25329