From 1549ee4b2a7582006038148dc089e166fc06d499 Mon Sep 17 00:00:00 2001
From: wk333 <13474090681@163.com>
Date: Mon, 17 Apr 2023 17:27:21 +0800
Subject: [PATCH] Fix CVE-2023-28708
---
CVE-2023-28708-pre.patch | 238 +++++++++++++++++++++++++++++++++++++++
CVE-2023-28708.patch | 232 ++++++++++++++++++++++++++++++++++++++
tomcat.spec | 7 +-
3 files changed, 476 insertions(+), 1 deletion(-)
create mode 100644 CVE-2023-28708-pre.patch
create mode 100644 CVE-2023-28708.patch
diff --git a/CVE-2023-28708-pre.patch b/CVE-2023-28708-pre.patch
new file mode 100644
index 0000000..01ed17b
--- /dev/null
+++ b/CVE-2023-28708-pre.patch
@@ -0,0 +1,238 @@
+From 09e214c09c78a48ea96b0137555b3c2a98a1bfab Mon Sep 17 00:00:00 2001
+From: Mark Thomas
+Date: Tue, 31 Mar 2020 14:03:17 +0100
+Subject: [PATCH] Make the HTTP/2 connection ID and stream Id available to
+ applications
+Origin: https://github.com/apache/tomcat/commit/09e214c09c78a48ea96b0137555b3c2a98a1bfab
+
+---
+ java/org/apache/catalina/Globals.java | 16 ++++++++
+ .../apache/catalina/connector/Request.java | 27 +++++++++++++
+ java/org/apache/coyote/AbstractProcessor.java | 39 +++++++++++++++++++
+ java/org/apache/coyote/ActionCode.java | 14 ++++++-
+ .../apache/coyote/http2/StreamProcessor.java | 12 ++++++
+ webapps/docs/changelog.xml | 5 +++
+ webapps/docs/config/http2.xml | 9 +++++
+ 7 files changed, 121 insertions(+), 1 deletion(-)
+
+diff --git a/java/org/apache/catalina/Globals.java b/java/org/apache/catalina/Globals.java
+index 994902b..c19d69c 100644
+--- a/java/org/apache/catalina/Globals.java
++++ b/java/org/apache/catalina/Globals.java
+@@ -112,6 +112,22 @@ public final class Globals {
+ "org.apache.catalina.NAMED";
+
+
++ /**
++ * The request attribute used to expose the current connection ID associated
++ * with the request, if any. Used with multiplexing protocols such as
++ * HTTTP/2.
++ */
++ public static final String CONNECTION_ID = "org.apache.coyote.connectionID";
++
++
++ /**
++ * The request attribute used to expose the current stream ID associated
++ * with the request, if any. Used with multiplexing protocols such as
++ * HTTTP/2.
++ */
++ public static final String STREAM_ID = "org.apache.coyote.streamID";
++
++
+ /**
+ * The servlet context attribute under which we store a flag used
+ * to mark this request as having been processed by the SSIServlet.
+diff --git a/java/org/apache/catalina/connector/Request.java b/java/org/apache/catalina/connector/Request.java
+index c4cc26a..94065ef 100644
+--- a/java/org/apache/catalina/connector/Request.java
++++ b/java/org/apache/catalina/connector/Request.java
+@@ -40,6 +40,7 @@ import java.util.TimeZone;
+ import java.util.TreeMap;
+ import java.util.concurrent.ConcurrentHashMap;
+ import java.util.concurrent.atomic.AtomicBoolean;
++import java.util.concurrent.atomic.AtomicReference;
+
+ import javax.naming.NamingException;
+ import javax.security.auth.Subject;
+@@ -3487,6 +3488,32 @@ public class Request implements HttpServletRequest {
+ // NO-OP
+ }
+ });
++ specialAttributes.put(Globals.CONNECTION_ID,
++ new SpecialAttributeAdapter() {
++ @Override
++ public Object get(Request request, String name) {
++ AtomicReference
+
++ Requests processed using HTTP/2 will have the following additional request
++ attributes available:
++
++ org.apache.coyote.connectionID will return the HTTP/2
++ connection ID
++ org.apache.coyote.streamID will return the HTTP/2 stream
++ ID
++
++
+
+
+
+--
+2.33.0
+
diff --git a/CVE-2023-28708.patch b/CVE-2023-28708.patch
new file mode 100644
index 0000000..1d03fc7
--- /dev/null
+++ b/CVE-2023-28708.patch
@@ -0,0 +1,232 @@
+From 3b51230764da595bb19e8d0962dd8c69ab40dfab Mon Sep 17 00:00:00 2001
+From: lihan
+Date: Fri, 10 Feb 2023 10:01:27 +0800
+Subject: [PATCH] Fix BZ 66471 - JSessionId secure attribute missing with
+ RemoteIpFilter and X-Forwarded-Proto set to https
+
+https://bz.apache.org/bugzilla/show_bug.cgi?id=66471
+
+Origin: https://github.com/apache/tomcat/commit/3b51230764da595bb19e8d0962dd8c69ab40dfab
+---
+ java/org/apache/catalina/Globals.java | 8 ++
+ .../apache/catalina/connector/Request.java | 14 +++
+ .../catalina/filters/RemoteIpFilter.java | 7 +-
+ .../catalina/filters/TestRemoteIpFilter.java | 96 ++++++++++++++-----
+ webapps/docs/changelog.xml | 5 +
+ 5 files changed, 101 insertions(+), 29 deletions(-)
+
+diff --git a/java/org/apache/catalina/Globals.java b/java/org/apache/catalina/Globals.java
+index c19d69c..2e9a377 100644
+--- a/java/org/apache/catalina/Globals.java
++++ b/java/org/apache/catalina/Globals.java
+@@ -160,6 +160,14 @@ public final class Globals {
+ org.apache.coyote.Constants.SENDFILE_SUPPORTED_ATTR;
+
+
++ /**
++ * The request attribute that is set to the value of {@code Boolean.TRUE}
++ * if {@link org.apache.catalina.filters.RemoteIpFilter} determines
++ * that this request was submitted via a secure channel.
++ */
++ public static final String REMOTE_IP_FILTER_SECURE = "org.apache.catalina.filters.RemoteIpFilter.secure";
++
++
+ /**
+ * The request attribute that can be used by a servlet to pass
+ * to the connector the name of the file that is to be served
+diff --git a/java/org/apache/catalina/connector/Request.java b/java/org/apache/catalina/connector/Request.java
+index 94065ef..889d5e7 100644
+--- a/java/org/apache/catalina/connector/Request.java
++++ b/java/org/apache/catalina/connector/Request.java
+@@ -3501,6 +3501,20 @@ public class Request implements HttpServletRequest {
+ // NO-OP
+ }
+ });
++ specialAttributes.put(Globals.REMOTE_IP_FILTER_SECURE,
++ new SpecialAttributeAdapter() {
++ @Override
++ public Object get(Request request, String name) {
++ return Boolean.valueOf(request.isSecure());
++ }
++
++ @Override
++ public void set(Request request, String name, Object value) {
++ if (value instanceof Boolean) {
++ request.setSecure(((Boolean) value).booleanValue());
++ }
++ }
++ });
+ specialAttributes.put(Globals.STREAM_ID,
+ new SpecialAttributeAdapter() {
+ @Override
+diff --git a/java/org/apache/catalina/filters/RemoteIpFilter.java b/java/org/apache/catalina/filters/RemoteIpFilter.java
+index b9f6655..e978cfb 100644
+--- a/java/org/apache/catalina/filters/RemoteIpFilter.java
++++ b/java/org/apache/catalina/filters/RemoteIpFilter.java
+@@ -577,11 +577,6 @@ public class RemoteIpFilter extends GenericFilter {
+ return serverPort;
+ }
+
+- @Override
+- public boolean isSecure() {
+- return secure;
+- }
+-
+ public void removeHeader(String name) {
+ Map.Entry> header = getHeaderEntry(name);
+ if (header != null) {
+@@ -617,7 +612,7 @@ public class RemoteIpFilter extends GenericFilter {
+ }
+
+ public void setSecure(boolean secure) {
+- this.secure = secure;
++ super.getRequest().setAttribute(Globals.REMOTE_IP_FILTER_SECURE, Boolean.valueOf(secure));
+ }
+
+ public void setServerPort(int serverPort) {
+diff --git a/test/org/apache/catalina/filters/TestRemoteIpFilter.java b/test/org/apache/catalina/filters/TestRemoteIpFilter.java
+index f7f2093..109fdd2 100644
+--- a/test/org/apache/catalina/filters/TestRemoteIpFilter.java
++++ b/test/org/apache/catalina/filters/TestRemoteIpFilter.java
+@@ -81,15 +81,21 @@ public class TestRemoteIpFilter extends TomcatBaseTest {
+
+ private static final long serialVersionUID = 1L;
+
+- private transient HttpServletRequest request;
+-
+- public HttpServletRequest getRequest() {
+- return request;
+- }
++ public String remoteAddr;
++ public String remoteHost;
++ public String scheme;
++ public String serverName;
++ public int serverPort;
++ public boolean isSecure;
+
+ @Override
+ public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+- this.request = request;
++ this.isSecure = request.isSecure();
++ this.remoteAddr = request.getRemoteAddr();
++ this.remoteHost = request.getRemoteHost();
++ this.scheme = request.getScheme();
++ this.serverName = request.getServerName();
++ this.serverPort = request.getServerPort();
+ PrintWriter writer = response.getWriter();
+
+ writer.println("request.remoteAddr=" + request.getRemoteAddr());
+@@ -127,16 +133,6 @@ public class TestRemoteIpFilter extends TomcatBaseTest {
+ getCoyoteRequest().scheme().setString(scheme);
+ }
+
+- @Override
+- public void setAttribute(String name, Object value) {
+- getCoyoteRequest().getAttributes().put(name, value);
+- }
+-
+- @Override
+- public Object getAttribute(String name) {
+- return getCoyoteRequest().getAttributes().get(name);
+- }
+-
+ @Override
+ public String getServerName() {
+ return "localhost";
+@@ -667,16 +663,70 @@ public class TestRemoteIpFilter extends TomcatBaseTest {
+
+ // VALIDATE
+ Assert.assertEquals(HttpURLConnection.HTTP_OK, httpURLConnection.getResponseCode());
+- HttpServletRequest request = mockServlet.getRequest();
+- Assert.assertNotNull(request);
+
+ // VALIDATE X-FORWARDED-FOR
+- Assert.assertEquals(expectedRemoteAddr, request.getRemoteAddr());
+- Assert.assertEquals(expectedRemoteAddr, request.getRemoteHost());
++ Assert.assertEquals(expectedRemoteAddr, mockServlet.remoteAddr);
++ Assert.assertEquals(expectedRemoteAddr, mockServlet.remoteHost);
+
+ // VALIDATE X-FORWARDED-PROTO
+- Assert.assertTrue(request.isSecure());
+- Assert.assertEquals("https", request.getScheme());
+- Assert.assertEquals(443, request.getServerPort());
++ Assert.assertTrue(mockServlet.isSecure);
++ Assert.assertEquals("https", mockServlet.scheme);
++ Assert.assertEquals(443, mockServlet.serverPort);
++ }
++
++ @Test
++ public void testJSessionIdSecureAttributeMissing() throws Exception {
++
++ // mostly default configuration : enable "x-forwarded-proto"
++ Map remoteIpFilterParameter = new HashMap<>();
++ remoteIpFilterParameter.put("protocolHeader", "x-forwarded-proto");
++
++ // SETUP
++ Tomcat tomcat = getTomcatInstance();
++ Context root = tomcat.addContext("", TEMP_DIR);
++
++ FilterDef filterDef = new FilterDef();
++ filterDef.getParameterMap().putAll(remoteIpFilterParameter);
++ filterDef.setFilterClass(RemoteIpFilter.class.getName());
++ filterDef.setFilterName(RemoteIpFilter.class.getName());
++
++ root.addFilterDef(filterDef);
++
++ FilterMap filterMap = new FilterMap();
++ filterMap.setFilterName(RemoteIpFilter.class.getName());
++ filterMap.addURLPatternDecoded("*");
++ root.addFilterMap(filterMap);
++
++ Bug66471Servlet bug66471Servlet = new Bug66471Servlet();
++
++ Tomcat.addServlet(root, bug66471Servlet.getClass().getName(), bug66471Servlet);
++ root.addServletMappingDecoded("/test", bug66471Servlet.getClass().getName());
++
++ getTomcatInstance().start();
++
++ Map> resHeaders = new HashMap<>();
++ Map> reqHeaders = new HashMap<>();
++ String expectedRemoteAddr = "my-remote-addr";
++ List forwardedFor = new ArrayList<>(1);
++ forwardedFor.add(expectedRemoteAddr);
++ List forwardedProto = new ArrayList<>(1);
++ forwardedProto.add("https");
++ reqHeaders.put("x-forwarded-for", forwardedFor);
++ reqHeaders.put("x-forwarded-proto", forwardedProto);
++
++ getUrl("http://localhost:" + tomcat.getConnector().getLocalPort() +
++ "/test", null, reqHeaders, resHeaders);
++ String setCookie = resHeaders.get("Set-Cookie").get(0);
++ Assert.assertTrue(setCookie.contains("Secure"));
++ Assert.assertTrue(bug66471Servlet.isSecure.booleanValue());
++ }
++ public static class Bug66471Servlet extends HttpServlet {
++ private static final long serialVersionUID = 1L;
++ public Boolean isSecure;
++ @Override
++ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
++ req.getSession();
++ isSecure = (Boolean) req.getAttribute(Globals.REMOTE_IP_FILTER_SECURE);
++ }
+ }
+ }
+diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
+index 8837628..15be3ed 100644
+--- a/webapps/docs/changelog.xml
++++ b/webapps/docs/changelog.xml
+@@ -478,6 +478,11 @@
+ Improve handling of overflow in the UTF-8 decoder with supplementary
+ characters. (markt)
+
++
++ 66471: Fix JSessionId secure attribute missing When
++ RemoteIpFilter determines that this request was submitted
++ via a secure channel. (lihan)
++
+
+
+
+--
+2.33.0
+
diff --git a/tomcat.spec b/tomcat.spec
index c3e0790..3612739 100644
--- a/tomcat.spec
+++ b/tomcat.spec
@@ -13,7 +13,7 @@
Name: tomcat
Epoch: 1
Version: %{major_version}.%{minor_version}.%{micro_version}
-Release: 29
+Release: 30
Summary: Implementation of the Java Servlet, JavaServer Pages, Java Expression Language and Java WebSocket technologies
License: ASL 2.0
URL: http://tomcat.apache.org/
@@ -102,6 +102,8 @@ Patch6057: CVE-2021-41079.patch
Patch6058: CVE-2021-42340.patch
Patch6069: CVE-2022-23181.patch
Patch6070: CVE-2022-42252.patch
+Patch6071: CVE-2023-28708-pre.patch
+Patch6072: CVE-2023-28708.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
@@ -503,6 +505,9 @@ fi
%{_javadocdir}/%{name}
%changelog
+* Mon Apr 17 2023 wangkai <13474090681@163.com> - 1:9.0.10-30
+- Fix CVE-2023-28708
+
* Wed Dec 21 2022 xulei - 1:9.0.10-29
- Fix CVE-2022-42252