From 53f748151dd919996ec0ae74a80c3f659ddd06f0 Mon Sep 17 00:00:00 2001 From: xu_lei_123 Date: Wed, 21 Dec 2022 14:56:18 +0800 Subject: [PATCH 1/4] fix CVE-2022-2048 --- CVE-2022-2048.patch | 194 ++++++++++++++++++++++++++++++++++++++++++++ jetty.spec | 6 +- 2 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 CVE-2022-2048.patch diff --git a/CVE-2022-2048.patch b/CVE-2022-2048.patch new file mode 100644 index 0000000..3e97c52 --- /dev/null +++ b/CVE-2022-2048.patch @@ -0,0 +1,194 @@ ++diff -uprN jetty.project-jetty-9.4.16.v20190411_back/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java jetty.project-jetty-9.4.16.v20190411_CVE-2022-2048/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java +--- jetty.project-jetty-9.4.16.v20190411_back/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java 2022-12-13 20:04:18.311000000 +0800 ++++ jetty.project-jetty-9.4.16.v20190411_CVE-2022-2048/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java 2022-12-14 14:51:07.431982708 +0800 +@@ -143,13 +143,13 @@ public class HttpChannelOverHTTP2 extend + } + catch (BadMessageException x) + { +- onBadMessage(x); +- return null; ++ if (LOG.isDebugEnabled()) ++ LOG.debug("onRequest", x); ++ return () -> onBadMessage(x); + } + catch (Throwable x) + { +- onBadMessage(new BadMessageException(HttpStatus.INTERNAL_SERVER_ERROR_500, null, x)); +- return null; ++ return () -> onBadMessage(new BadMessageException(HttpStatus.INTERNAL_SERVER_ERROR_500, null, x)); + } + } + +@@ -175,13 +175,11 @@ public class HttpChannelOverHTTP2 extend + } + catch (BadMessageException x) + { +- onBadMessage(x); +- return null; ++ return () -> onBadMessage(x); + } + catch (Throwable x) + { +- onBadMessage(new BadMessageException(HttpStatus.INTERNAL_SERVER_ERROR_500, null, x)); +- return null; ++ return () -> onBadMessage(new BadMessageException(HttpStatus.INTERNAL_SERVER_ERROR_500, null, x)); + } + } + +diff -uprN jetty.project-jetty-9.4.16.v20190411_back/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/BadURITest.java jetty.project-jetty-9.4.16.v20190411_CVE-2022-2048/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/BadURITest.java +--- jetty.project-jetty-9.4.16.v20190411_back/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java 2022-12-13 20:04:18.311000000 +0800 ++++ jetty.project-jetty-9.4.16.v20190411_CVE-2022-2048/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/BadURITest.java 2022-12-14 14:53:27.900550822 +0800 +@@ -0,0 +1,153 @@ ++// ++// ======================================================================== ++// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. ++// ++// This program and the accompanying materials are made available under the ++// terms of the Eclipse Public License v. 2.0 which is available at ++// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 ++// which is available at https://www.apache.org/licenses/LICENSE-2.0. ++// ++// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 ++// ======================================================================== ++// ++ ++package org.eclipse.jetty.http2.server; ++ ++import java.io.OutputStream; ++import java.net.Socket; ++import java.nio.ByteBuffer; ++import java.util.HashMap; ++import java.util.concurrent.CountDownLatch; ++import java.util.concurrent.TimeUnit; ++import javax.servlet.http.HttpServletRequest; ++import javax.servlet.http.HttpServletResponse; ++ ++import org.eclipse.jetty.http.HostPortHttpField; ++import org.eclipse.jetty.http.HttpFields; ++import org.eclipse.jetty.http.HttpMethod; ++import org.eclipse.jetty.http.HttpScheme; ++import org.eclipse.jetty.http.HttpVersion; ++import org.eclipse.jetty.http.MetaData; ++import org.eclipse.jetty.http2.frames.HeadersFrame; ++import org.eclipse.jetty.http2.frames.PrefaceFrame; ++import org.eclipse.jetty.http2.frames.SettingsFrame; ++import org.eclipse.jetty.http2.generator.Generator; ++import org.eclipse.jetty.io.ByteBufferPool; ++import org.eclipse.jetty.server.Handler; ++import org.eclipse.jetty.server.HttpConfiguration; ++import org.eclipse.jetty.server.Request; ++import org.eclipse.jetty.server.Server; ++import org.eclipse.jetty.server.ServerConnector; ++import org.eclipse.jetty.server.handler.AbstractHandler; ++import org.eclipse.jetty.server.handler.ErrorHandler; ++import org.eclipse.jetty.util.BufferUtil; ++import org.eclipse.jetty.util.component.LifeCycle; ++import org.junit.jupiter.api.AfterEach; ++import org.junit.jupiter.api.Test; ++ ++import static org.junit.jupiter.api.Assertions.assertTrue; ++ ++public class BadURITest ++{ ++ private Server server; ++ private ServerConnector connector; ++ ++ protected void startServer(Handler handler) throws Exception ++ { ++ server = new Server(); ++ connector = new ServerConnector(server, 1, 1, new HTTP2CServerConnectionFactory(new HttpConfiguration())); ++ server.addConnector(connector); ++ server.setHandler(handler); ++ server.start(); ++ } ++ ++ @AfterEach ++ public void dispose() ++ { ++ LifeCycle.stop(server); ++ } ++ ++ @Test ++ public void testBadURI() throws Exception ++ { ++ CountDownLatch handlerLatch = new CountDownLatch(1); ++ startServer(new AbstractHandler() ++ { ++ @Override ++ public void handle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) ++ { ++ jettyRequest.setHandled(true); ++ handlerLatch.countDown(); ++ } ++ }); ++ ++ // Remove existing ErrorHandlers. ++ while (true) ++ { ++ ErrorHandler errorHandler : server.getBeans(ErrorHandler.class)) ++ if (errorHandler == null) ++ break; ++ server.removeBean(errorHandler); ++ } ++ ++ server.addBean(new ErrorHandler() ++ { ++ @Override ++ public ByteBuffer badMessageError(int status, String reason, HttpFields.Mutable fields) ++ { ++ // TODO: flow control should be enough. ++ // Return a very large buffer that will cause HTTP/2 flow control exhaustion and/or TCP congestion. ++ return ByteBuffer.allocateDirect(128 * 1024 * 1024); ++ } ++ }); ++ ++ ByteBufferPool byteBufferPool = connector.getByteBufferPool(); ++ Generator generator = new Generator(byteBufferPool); ++ ++ // Craft a request with a bad URI, it will not hit the Handler. ++ MetaData.Request metaData1 = new MetaData.Request( ++ HttpMethod.GET.asString(), ++ HttpScheme.HTTP.asString(), ++ new HostPortHttpField("localhost:" + connector.getLocalPort()), ++ // Use an ambiguous path parameter so that the URI is invalid. ++ "/foo/..;/bar", ++ HttpVersion.HTTP_2, ++ HttpFields.EMPTY, ++ -1 ++ ); ++ ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool); ++ generator.control(lease, new PrefaceFrame()); ++ generator.control(lease, new SettingsFrame(new HashMap<>(), false)); ++ generator.control(lease, new HeadersFrame(1, metaData1, null, true)); ++ ++ try (Socket client = new Socket("localhost", connector.getLocalPort())) ++ { ++ OutputStream output = client.getOutputStream(); ++ for (ByteBuffer buffer : lease.getByteBuffers()) ++ { ++ output.write(BufferUtil.toArray(buffer)); ++ } ++ ++ // Wait for the first request be processed on the server. ++ Thread.sleep(1000); ++ ++ // Send a second request and verify that it hits the Handler. ++ lease.recycle(); ++ MetaData.Request metaData2 = new MetaData.Request( ++ HttpMethod.GET.asString(), ++ HttpScheme.HTTP.asString(), ++ new HostPortHttpField("localhost:" + connector.getLocalPort()), ++ "/valid", ++ HttpVersion.HTTP_2, ++ HttpFields.EMPTY, ++ -1 ++ ); ++ generator.control(lease, new HeadersFrame(3, metaData2, null, true)); ++ for (ByteBuffer buffer : lease.getByteBuffers()) ++ { ++ output.write(BufferUtil.toArray(buffer)); ++ } ++ assertTrue(handlerLatch.await(5, TimeUnit.SECONDS)); ++ } ++ } ++} diff --git a/jetty.spec b/jetty.spec index 3470520..6580854 100644 --- a/jetty.spec +++ b/jetty.spec @@ -12,7 +12,7 @@ %bcond_with jp_minimal Name: jetty Version: 9.4.16 -Release: 2 +Release: 3 Summary: Java Webserver and Servlet Container License: ASL 2.0 or EPL-1.0 or EPL-2.0 URL: http://www.eclipse.org/jetty/ @@ -26,6 +26,7 @@ Patch1: CVE-2020-27223.patch Patch2: CVE-2021-28165.patch Patch3: CVE-2021-28169.patch Patch4: CVE-2021-34428.patch +Patch5: CVE-2022-2048.patch BuildRequires: maven-local mvn(javax.servlet:javax.servlet-api) BuildRequires: mvn(org.apache.felix:maven-bundle-plugin) @@ -786,6 +787,9 @@ exit 0 %license LICENSE NOTICE.txt LICENSE-MIT %changelog +* Wed Dec 21 2022 xulei - 9.4.16-3 +- fix CVE-2022-2048 + * Mon Oct 24 2022 yaoxin - 9.4.16-2 - fix selfbuild error -- Gitee From 61ce2690522421d0d09e7b7d381a5e1fbf16b973 Mon Sep 17 00:00:00 2001 From: xu_lei_123 Date: Wed, 21 Dec 2022 15:14:58 +0800 Subject: [PATCH 2/4] fix CVE-2022-2048 --- CVE-2022-2048.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CVE-2022-2048.patch b/CVE-2022-2048.patch index 3e97c52..6a722e3 100644 --- a/CVE-2022-2048.patch +++ b/CVE-2022-2048.patch @@ -36,7 +36,7 @@ } diff -uprN jetty.project-jetty-9.4.16.v20190411_back/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/BadURITest.java jetty.project-jetty-9.4.16.v20190411_CVE-2022-2048/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/BadURITest.java ---- jetty.project-jetty-9.4.16.v20190411_back/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java 2022-12-13 20:04:18.311000000 +0800 +--- jetty.project-jetty-9.4.16.v20190411_back/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/BadURITest.java 2022-12-13 20:04:18.311000000 +0800 +++ jetty.project-jetty-9.4.16.v20190411_CVE-2022-2048/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/BadURITest.java 2022-12-14 14:53:27.900550822 +0800 @@ -0,0 +1,153 @@ +// -- Gitee From 5e723f0a17850a82dd139a5e3f996fc0846067e3 Mon Sep 17 00:00:00 2001 From: xu_lei_123 Date: Wed, 21 Dec 2022 17:18:40 +0800 Subject: [PATCH 3/4] fix CVE-2022-2048 --- CVE-2022-2048.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CVE-2022-2048.patch b/CVE-2022-2048.patch index 6a722e3..a546d27 100644 --- a/CVE-2022-2048.patch +++ b/CVE-2022-2048.patch @@ -125,7 +125,7 @@ diff -uprN jetty.project-jetty-9.4.16.v20190411_back/jetty-http2/http2-server/sr + // Remove existing ErrorHandlers. + while (true) + { -+ ErrorHandler errorHandler : server.getBeans(ErrorHandler.class)) ++ ErrorHandler errorHandler : server.getBeans(ErrorHandler.class)); + if (errorHandler == null) + break; + server.removeBean(errorHandler); -- Gitee From c8659397899ed2c717b2f7c11d277540f78fa1cc Mon Sep 17 00:00:00 2001 From: xu_lei_123 Date: Wed, 21 Dec 2022 17:34:22 +0800 Subject: [PATCH 4/4] fix CVE-2022-2047 --- CVE-2022-2047.patch | 302 ++++++++++++++++++++++++++++++++++++++++++++ CVE-2022-2048.patch | 194 ---------------------------- jetty.spec | 4 +- 3 files changed, 304 insertions(+), 196 deletions(-) create mode 100644 CVE-2022-2047.patch delete mode 100644 CVE-2022-2048.patch diff --git a/CVE-2022-2047.patch b/CVE-2022-2047.patch new file mode 100644 index 0000000..2e73f7a --- /dev/null +++ b/CVE-2022-2047.patch @@ -0,0 +1,302 @@ +diff -uprN jetty.project-jetty-9.4.16.v20190411_back/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRequest.java jetty.project-jetty-9.4.16.v20190411/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRequest.java +--- jetty.project-jetty-9.4.16.v20190411_back/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRequest.java 2022-12-13 20:04:18.237000000 +0800 ++++ jetty.project-jetty-9.4.16.v20190411/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRequest.java 2022-12-13 15:49:40.806121800 +0800 +@@ -177,6 +177,8 @@ public class HttpRequest implements Requ + String rawPath = uri.getRawPath(); + if (rawPath == null) + rawPath = ""; ++ if (!rawPath.startsWith("/")) ++ rawPath = "/" + rawPath; + this.path = rawPath; + String query = uri.getRawQuery(); + if (query != null) +@@ -855,14 +857,14 @@ public class HttpRequest implements Requ + return result; + } + +- private URI newURI(String uri) ++ private URI newURI(String path) + { + try + { + // Handle specially the "OPTIONS *" case, since it is possible to create a URI from "*" (!). +- if ("*".equals(uri)) ++ if ("*".equals(path)) + return null; +- URI result = new URI(uri); ++ URI result = new URI(path); + return result.isOpaque() ? null : result; + } + catch (URISyntaxException x) +diff -uprN jetty.project-jetty-9.4.16.v20190411_back/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientURITest.java jetty.project-jetty-9.4.16.v20190411/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientURITest.java +--- jetty.project-jetty-9.4.16.v20190411_back/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientURITest.java 2022-12-13 20:04:18.241000000 +0800 ++++ jetty.project-jetty-9.4.16.v20190411/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientURITest.java 2022-12-13 15:49:33.335326400 +0800 +@@ -36,8 +36,10 @@ import java.net.SocketException; + import java.net.URLEncoder; + import java.nio.charset.StandardCharsets; + import java.util.Locale; ++import java.util.concurrent.CountDownLatch; + import java.util.concurrent.ExecutionException; + import java.util.concurrent.TimeUnit; ++import java.util.concurrent.atomic.AtomicReference; + + import javax.servlet.ServletException; + import javax.servlet.http.HttpServletRequest; +@@ -79,6 +81,49 @@ public class HttpClientURITest extends A + } + + @ParameterizedTest ++ @ArgumentsSource(ScenarioProvider.class) ++ public void testPathWithPathParameter(Scenario scenario) throws Exception ++ { ++ AtomicReference serverLatchRef = new AtomicReference<>(); ++ start(scenario, new EmptyServerHandler() ++ { ++ @Override ++ protected void service(String target, org.eclipse.jetty.server.Request jettyRequest, HttpServletRequest request, HttpServletResponse response) ++ { ++ if (jettyRequest.getHttpURI().hasAmbiguousEmptySegment()) ++ response.setStatus(400); ++ serverLatchRef.get().countDown(); ++ } ++ }); ++ ++ serverLatchRef.set(new CountDownLatch(1)); ++ ContentResponse response1 = client.newRequest("localhost", connector.getLocalPort()) ++ .scheme(scenario.getScheme()) ++ .path("/url;p=v") ++ .send(); ++ assertEquals(HttpStatus.OK_200, response1.getStatus()); ++ assertTrue(serverLatchRef.get().await(5, TimeUnit.SECONDS)); ++ ++ // Ambiguous empty segment. ++ serverLatchRef.set(new CountDownLatch(1)); ++ ContentResponse response2 = client.newRequest("localhost", connector.getLocalPort()) ++ .scheme(scenario.getScheme()) ++ .path(";p=v/url") ++ .send(); ++ assertEquals(HttpStatus.BAD_REQUEST_400, response2.getStatus()); ++ assertTrue(serverLatchRef.get().await(5, TimeUnit.SECONDS)); ++ ++ // Ambiguous empty segment. ++ serverLatchRef.set(new CountDownLatch(1)); ++ ContentResponse response3 = client.newRequest("localhost", connector.getLocalPort()) ++ .scheme(scenario.getScheme()) ++ .path(";@host.org/url") ++ .send(); ++ assertEquals(HttpStatus.BAD_REQUEST_400, response3.getStatus()); ++ assertTrue(serverLatchRef.get().await(5, TimeUnit.SECONDS)); ++ } ++ ++ @ParameterizedTest + @ArgumentsSource(ScenarioProvider.class) + public void testIDNHost(Scenario scenario) throws Exception + { +diff -uprN jetty.project-jetty-9.4.16.v20190411_back/jetty-http/src/main/java/org/eclipse/jetty/http/HttpURI.java jetty.project-jetty-9.4.16.v20190411/jetty-http/src/main/java/org/eclipse/jetty/http/HttpURI.java +--- jetty.project-jetty-9.4.16.v20190411_back/jetty-http/src/main/java/org/eclipse/jetty/http/HttpURI.java 2022-12-13 20:04:18.285000000 +0800 ++++ jetty.project-jetty-9.4.16.v20190411/jetty-http/src/main/java/org/eclipse/jetty/http/HttpURI.java 2022-12-13 21:48:14.310756581 +0800 +@@ -189,7 +189,7 @@ public class HttpURI + _uri=uri; + + if (HttpMethod.CONNECT.is(method)) +- _path=uri; ++ parse(State.HOST, uri, 0, uri.length()); + else + parse(uri.startsWith("/")?State.PATH:State.START,uri,0,uri.length()); + } +@@ -720,35 +720,55 @@ public class HttpURI + */ + public void setAuthority(String host, int port) + { ++ if (host != null && !isPathValidForAuthority(_path)) ++ throw new IllegalArgumentException("Relative path with authority"); + _host=host; + _port=port; + _uri=null; + } + ++ private boolean isPathValidForAuthority(String path) ++ { ++ if (path == null) ++ return true; ++ if (path.isEmpty() || "*".equals(path)) ++ return true; ++ return path.startsWith("/"); ++ } ++ + /* ------------------------------------------------------------ */ + /** + * @param path the path + */ + public void setPath(String path) + { ++ if (hasAuthority() && !isPathValidForAuthority(path)) ++ throw new IllegalArgumentException("Relative path with authority"); + _uri=null; + _path=path; + _decodedPath=null; + } + + /* ------------------------------------------------------------ */ +- public void setPathQuery(String path) ++ public void setPathQuery(String pathQuery) + { ++ if (hasAuthority() && !isPathValidForAuthority(pathQuery)) ++ throw new IllegalArgumentException("Relative path with authority"); + _uri=null; + _path=null; + _decodedPath=null; + _param=null; + _fragment=null; +- if (path!=null) +- parse(State.PATH,path,0,path.length()); ++ if (pathQuery!=null) ++ parse(State.PATH,pathQuery,0,pathQuery.length()); + } + + /* ------------------------------------------------------------ */ ++ private boolean hasAuthority() ++ { ++ return _host != null; ++ } ++ + public void setQuery(String query) + { + _query=query; +diff -uprN jetty.project-jetty-9.4.16.v20190411_back/jetty-http/src/test/java/org/eclipse/jetty/http/HttpURITest.java jetty.project-jetty-9.4.16.v20190411/jetty-http/src/test/java/org/eclipse/jetty/http/HttpURITest.java +--- jetty.project-jetty-9.4.16.v20190411_back/jetty-http/src/test/java/org/eclipse/jetty/http/HttpURITest.java 2022-12-13 20:04:18.288000000 +0800 ++++ jetty.project-jetty-9.4.16.v20190411/jetty-http/src/test/java/org/eclipse/jetty/http/HttpURITest.java 2022-12-13 15:49:24.364726300 +0800 +@@ -101,6 +101,32 @@ public class HttpURITest + } + + @Test ++ public void testCONNECT() ++ { ++ HttpURI uri = new HttpURI(); ++ ++ uri.parseRequestTarget("CONNECT", "host:80"); ++ assertThat(uri.getHost(), is("host")); ++ assertThat(uri.getPort(), is(80)); ++ assertThat(uri.getPath(), nullValue()); ++ ++ uri.parseRequestTarget("CONNECT", "host"); ++ assertThat(uri.getHost(), is("host")); ++ assertThat(uri.getPort(), is(-1)); ++ assertThat(uri.getPath(), nullValue()); ++ ++ uri.parseRequestTarget("CONNECT", "192.168.0.1:8080"); ++ assertThat(uri.getHost(), is("192.168.0.1")); ++ assertThat(uri.getPort(), is(8080)); ++ assertThat(uri.getPath(), nullValue()); ++ ++ uri.parseRequestTarget("CONNECT", "[::1]:8080"); ++ assertThat(uri.getHost(), is("[::1]")); ++ assertThat(uri.getPort(), is(8080)); ++ assertThat(uri.getPath(), nullValue()); ++ } ++ ++ @Test + public void testExtB() throws Exception + { + for (String value: new String[]{"a","abcdABCD","\u00C0","\u697C","\uD869\uDED5","\uD840\uDC08"} ) +@@ -222,4 +248,64 @@ public class HttpURITest + assertEquals(uri.getAuthority(), "example.com:8888"); + assertEquals(uri.getUser(), "user:password"); + } ++ ++ @Test ++ public void testRelativePathWithAuthority() ++ { ++ assertThrows(IllegalArgumentException.class, () -> ++ { ++ HttpURI httpURI = new HttpURI(); ++ httpURI.setAuthority("host", 0); ++ httpURI.setPath("path"); ++ }); ++ assertThrows(IllegalArgumentException.class, () -> ++ { ++ HttpURI httpURI = new HttpURI(); ++ httpURI.setAuthority("host", 8080); ++ httpURI.setPath(";p=v/url"); ++ }); ++ assertThrows(IllegalArgumentException.class, () -> ++ { ++ HttpURI httpURI = new HttpURI(); ++ httpURI.setAuthority("host", 0); ++ httpURI.setPath(";"); ++ }); ++ ++ assertThrows(IllegalArgumentException.class, () -> ++ { ++ HttpURI httpURI = new HttpURI(); ++ httpURI.setPath("path"); ++ httpURI.setAuthority("host", 0); ++ }); ++ assertThrows(IllegalArgumentException.class, () -> ++ { ++ HttpURI httpURI = new HttpURI(); ++ httpURI.setPath(";p=v/url"); ++ httpURI.setAuthority("host", 8080); ++ }); ++ assertThrows(IllegalArgumentException.class, () -> ++ { ++ HttpURI httpURI = new HttpURI(); ++ httpURI.setPath(";"); ++ httpURI.setAuthority("host", 0); ++ }); ++ ++ HttpURI uri = new HttpURI(); ++ uri.setPath("*"); ++ uri.setAuthority("host", 0); ++ assertEquals("//host*", uri.toString()); ++ uri = new HttpURI(); ++ uri.setAuthority("host", 0); ++ uri.setPath("*"); ++ assertEquals("//host*", uri.toString()); ++ ++ uri = new HttpURI(); ++ uri.setPath(""); ++ uri.setAuthority("host", 0); ++ assertEquals("//host", uri.toString()); ++ uri = new HttpURI(); ++ uri.setAuthority("host", 0); ++ uri.setPath(""); ++ assertEquals("//host", uri.toString()); ++ } + } +diff -uprN jetty.project-jetty-9.4.16.v20190411_back/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ConnectHandler.java jetty.project-jetty-9.4.16.v20190411/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ConnectHandler.java +--- jetty.project-jetty-9.4.16.v20190411_back/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ConnectHandler.java 2022-12-13 20:04:18.361000000 +0800 ++++ jetty.project-jetty-9.4.16.v20190411/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ConnectHandler.java 2022-12-13 15:48.14.684794100 +0800 +@@ -197,7 +197,7 @@ public class ConnectHandler extends Hand + { + if (HttpMethod.CONNECT.is(request.getMethod())) + { +- String serverAddress = request.getRequestURI(); ++ String serverAddress = baseRequest.getHttpURI().getAuthority(); + if (LOG.isDebugEnabled()) + LOG.debug("CONNECT request for {}", serverAddress); + +diff -uprN jetty.project-jetty-9.4.16.v20190411_back/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java jetty.project-jetty-9.4.16.v20190411/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java +--- jetty.project-jetty-9.4.16.v20190411_back/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java 2022-12-13 20:04:18.377000000 +0800 ++++ jetty.project-jetty-9.4.16.v20190411/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java 2022-12-13 15:48.14.151348100 +0800 +@@ -1778,9 +1778,18 @@ public class Request implements HttpServ + + setMethod(request.getMethod()); + HttpURI uri = request.getURI(); +- _originalURI = uri.isAbsolute()&&request.getHttpVersion()!=HttpVersion.HTTP_2?uri.toString():uri.getPathQuery(); ++ String encoded; ++ if (HttpMethod.CONNECT.is(request.getMethod())) ++ { ++ _originalURI = uri.getAuthority(); ++ encoded = "/"; ++ } ++ else ++ { ++ _originalURI = uri.isAbsolute() && request.getHttpVersion() != HttpVersion.HTTP_2 ? uri.toString() : uri.getPathQuery(); ++ encoded = uri.getPath(); ++ } + +- String encoded = uri.getPath(); + String path; + if (encoded==null) + { diff --git a/CVE-2022-2048.patch b/CVE-2022-2048.patch deleted file mode 100644 index a546d27..0000000 --- a/CVE-2022-2048.patch +++ /dev/null @@ -1,194 +0,0 @@ -+diff -uprN jetty.project-jetty-9.4.16.v20190411_back/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java jetty.project-jetty-9.4.16.v20190411_CVE-2022-2048/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java ---- jetty.project-jetty-9.4.16.v20190411_back/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java 2022-12-13 20:04:18.311000000 +0800 -+++ jetty.project-jetty-9.4.16.v20190411_CVE-2022-2048/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HttpChannelOverHTTP2.java 2022-12-14 14:51:07.431982708 +0800 -@@ -143,13 +143,13 @@ public class HttpChannelOverHTTP2 extend - } - catch (BadMessageException x) - { -- onBadMessage(x); -- return null; -+ if (LOG.isDebugEnabled()) -+ LOG.debug("onRequest", x); -+ return () -> onBadMessage(x); - } - catch (Throwable x) - { -- onBadMessage(new BadMessageException(HttpStatus.INTERNAL_SERVER_ERROR_500, null, x)); -- return null; -+ return () -> onBadMessage(new BadMessageException(HttpStatus.INTERNAL_SERVER_ERROR_500, null, x)); - } - } - -@@ -175,13 +175,11 @@ public class HttpChannelOverHTTP2 extend - } - catch (BadMessageException x) - { -- onBadMessage(x); -- return null; -+ return () -> onBadMessage(x); - } - catch (Throwable x) - { -- onBadMessage(new BadMessageException(HttpStatus.INTERNAL_SERVER_ERROR_500, null, x)); -- return null; -+ return () -> onBadMessage(new BadMessageException(HttpStatus.INTERNAL_SERVER_ERROR_500, null, x)); - } - } - -diff -uprN jetty.project-jetty-9.4.16.v20190411_back/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/BadURITest.java jetty.project-jetty-9.4.16.v20190411_CVE-2022-2048/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/BadURITest.java ---- jetty.project-jetty-9.4.16.v20190411_back/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/BadURITest.java 2022-12-13 20:04:18.311000000 +0800 -+++ jetty.project-jetty-9.4.16.v20190411_CVE-2022-2048/jetty-http2/http2-server/src/test/java/org/eclipse/jetty/http2/server/BadURITest.java 2022-12-14 14:53:27.900550822 +0800 -@@ -0,0 +1,153 @@ -+// -+// ======================================================================== -+// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -+// -+// This program and the accompanying materials are made available under the -+// terms of the Eclipse Public License v. 2.0 which is available at -+// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -+// which is available at https://www.apache.org/licenses/LICENSE-2.0. -+// -+// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -+// ======================================================================== -+// -+ -+package org.eclipse.jetty.http2.server; -+ -+import java.io.OutputStream; -+import java.net.Socket; -+import java.nio.ByteBuffer; -+import java.util.HashMap; -+import java.util.concurrent.CountDownLatch; -+import java.util.concurrent.TimeUnit; -+import javax.servlet.http.HttpServletRequest; -+import javax.servlet.http.HttpServletResponse; -+ -+import org.eclipse.jetty.http.HostPortHttpField; -+import org.eclipse.jetty.http.HttpFields; -+import org.eclipse.jetty.http.HttpMethod; -+import org.eclipse.jetty.http.HttpScheme; -+import org.eclipse.jetty.http.HttpVersion; -+import org.eclipse.jetty.http.MetaData; -+import org.eclipse.jetty.http2.frames.HeadersFrame; -+import org.eclipse.jetty.http2.frames.PrefaceFrame; -+import org.eclipse.jetty.http2.frames.SettingsFrame; -+import org.eclipse.jetty.http2.generator.Generator; -+import org.eclipse.jetty.io.ByteBufferPool; -+import org.eclipse.jetty.server.Handler; -+import org.eclipse.jetty.server.HttpConfiguration; -+import org.eclipse.jetty.server.Request; -+import org.eclipse.jetty.server.Server; -+import org.eclipse.jetty.server.ServerConnector; -+import org.eclipse.jetty.server.handler.AbstractHandler; -+import org.eclipse.jetty.server.handler.ErrorHandler; -+import org.eclipse.jetty.util.BufferUtil; -+import org.eclipse.jetty.util.component.LifeCycle; -+import org.junit.jupiter.api.AfterEach; -+import org.junit.jupiter.api.Test; -+ -+import static org.junit.jupiter.api.Assertions.assertTrue; -+ -+public class BadURITest -+{ -+ private Server server; -+ private ServerConnector connector; -+ -+ protected void startServer(Handler handler) throws Exception -+ { -+ server = new Server(); -+ connector = new ServerConnector(server, 1, 1, new HTTP2CServerConnectionFactory(new HttpConfiguration())); -+ server.addConnector(connector); -+ server.setHandler(handler); -+ server.start(); -+ } -+ -+ @AfterEach -+ public void dispose() -+ { -+ LifeCycle.stop(server); -+ } -+ -+ @Test -+ public void testBadURI() throws Exception -+ { -+ CountDownLatch handlerLatch = new CountDownLatch(1); -+ startServer(new AbstractHandler() -+ { -+ @Override -+ public void handle(String target, Request jettyRequest, HttpServletRequest request, HttpServletResponse response) -+ { -+ jettyRequest.setHandled(true); -+ handlerLatch.countDown(); -+ } -+ }); -+ -+ // Remove existing ErrorHandlers. -+ while (true) -+ { -+ ErrorHandler errorHandler : server.getBeans(ErrorHandler.class)); -+ if (errorHandler == null) -+ break; -+ server.removeBean(errorHandler); -+ } -+ -+ server.addBean(new ErrorHandler() -+ { -+ @Override -+ public ByteBuffer badMessageError(int status, String reason, HttpFields.Mutable fields) -+ { -+ // TODO: flow control should be enough. -+ // Return a very large buffer that will cause HTTP/2 flow control exhaustion and/or TCP congestion. -+ return ByteBuffer.allocateDirect(128 * 1024 * 1024); -+ } -+ }); -+ -+ ByteBufferPool byteBufferPool = connector.getByteBufferPool(); -+ Generator generator = new Generator(byteBufferPool); -+ -+ // Craft a request with a bad URI, it will not hit the Handler. -+ MetaData.Request metaData1 = new MetaData.Request( -+ HttpMethod.GET.asString(), -+ HttpScheme.HTTP.asString(), -+ new HostPortHttpField("localhost:" + connector.getLocalPort()), -+ // Use an ambiguous path parameter so that the URI is invalid. -+ "/foo/..;/bar", -+ HttpVersion.HTTP_2, -+ HttpFields.EMPTY, -+ -1 -+ ); -+ ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool); -+ generator.control(lease, new PrefaceFrame()); -+ generator.control(lease, new SettingsFrame(new HashMap<>(), false)); -+ generator.control(lease, new HeadersFrame(1, metaData1, null, true)); -+ -+ try (Socket client = new Socket("localhost", connector.getLocalPort())) -+ { -+ OutputStream output = client.getOutputStream(); -+ for (ByteBuffer buffer : lease.getByteBuffers()) -+ { -+ output.write(BufferUtil.toArray(buffer)); -+ } -+ -+ // Wait for the first request be processed on the server. -+ Thread.sleep(1000); -+ -+ // Send a second request and verify that it hits the Handler. -+ lease.recycle(); -+ MetaData.Request metaData2 = new MetaData.Request( -+ HttpMethod.GET.asString(), -+ HttpScheme.HTTP.asString(), -+ new HostPortHttpField("localhost:" + connector.getLocalPort()), -+ "/valid", -+ HttpVersion.HTTP_2, -+ HttpFields.EMPTY, -+ -1 -+ ); -+ generator.control(lease, new HeadersFrame(3, metaData2, null, true)); -+ for (ByteBuffer buffer : lease.getByteBuffers()) -+ { -+ output.write(BufferUtil.toArray(buffer)); -+ } -+ assertTrue(handlerLatch.await(5, TimeUnit.SECONDS)); -+ } -+ } -+} diff --git a/jetty.spec b/jetty.spec index 6580854..cd357e5 100644 --- a/jetty.spec +++ b/jetty.spec @@ -26,7 +26,7 @@ Patch1: CVE-2020-27223.patch Patch2: CVE-2021-28165.patch Patch3: CVE-2021-28169.patch Patch4: CVE-2021-34428.patch -Patch5: CVE-2022-2048.patch +Patch5: CVE-2022-2047.patch BuildRequires: maven-local mvn(javax.servlet:javax.servlet-api) BuildRequires: mvn(org.apache.felix:maven-bundle-plugin) @@ -788,7 +788,7 @@ exit 0 %changelog * Wed Dec 21 2022 xulei - 9.4.16-3 -- fix CVE-2022-2048 +- fix CVE-2022-2047 * Mon Oct 24 2022 yaoxin - 9.4.16-2 - fix selfbuild error -- Gitee