From 9ef18780ccce8d444bcab4f040d8991ca63f88fe Mon Sep 17 00:00:00 2001 From: hamadodene Date: Mon, 8 Aug 2022 16:50:55 +0200 Subject: [PATCH] Disable http trace method in jetty --- .../carapaceproxy/core/HttpProxyServer.java | 52 ++++++++++++++++--- .../core/JettyHttpTraceMethodTest.java | 25 +++++++++ 2 files changed, 69 insertions(+), 8 deletions(-) create mode 100644 carapace-server/src/test/java/org/carapaceproxy/core/JettyHttpTraceMethodTest.java diff --git a/carapace-server/src/main/java/org/carapaceproxy/core/HttpProxyServer.java b/carapace-server/src/main/java/org/carapaceproxy/core/HttpProxyServer.java index 247868ce2..6458f8f1e 100644 --- a/carapace-server/src/main/java/org/carapaceproxy/core/HttpProxyServer.java +++ b/carapace-server/src/main/java/org/carapaceproxy/core/HttpProxyServer.java @@ -20,7 +20,9 @@ package org.carapaceproxy.core; import com.google.common.annotations.VisibleForTesting; +import io.netty.handler.codec.http.HttpMethod; import io.prometheus.client.exporter.MetricsServlet; + import java.io.File; import java.io.FileInputStream; import java.lang.reflect.InvocationTargetException; @@ -38,6 +40,7 @@ import java.util.logging.Logger; import javax.naming.ConfigurationException; import javax.servlet.DispatcherType; + import org.apache.bookkeeper.stats.*; import org.apache.commons.configuration.PropertiesConfiguration; import org.carapaceproxy.server.mapper.EndpointMapper; @@ -47,9 +50,11 @@ import org.carapaceproxy.cluster.GroupMembershipHandler; import org.carapaceproxy.cluster.impl.NullGroupMembershipHandler; import org.carapaceproxy.cluster.impl.ZooKeeperGroupMembershipHandler; + import static org.carapaceproxy.cluster.impl.ZooKeeperGroupMembershipHandler.PROPERTY_PEER_ADMIN_SERVER_HOST; import static org.carapaceproxy.cluster.impl.ZooKeeperGroupMembershipHandler.PROPERTY_PEER_ADMIN_SERVER_PORT; import static org.carapaceproxy.cluster.impl.ZooKeeperGroupMembershipHandler.PROPERTY_PEER_ADMIN_SERVER_HTTPS_PORT; + import org.carapaceproxy.configstore.CertificateData; import org.carapaceproxy.configstore.ConfigurationStore; import org.carapaceproxy.configstore.HerdDBConfigurationStore; @@ -62,23 +67,23 @@ import org.carapaceproxy.server.config.NetworkListenerConfiguration; import org.carapaceproxy.server.config.RequestFilterConfiguration; import org.carapaceproxy.server.config.SSLCertificateConfiguration; + import static org.carapaceproxy.server.filters.RequestFilterFactory.buildRequestFilter; + import org.carapaceproxy.user.SimpleUserRealm; import org.carapaceproxy.user.UserRealm; -import org.eclipse.jetty.server.HttpConfiguration; -import org.eclipse.jetty.server.HttpConnectionFactory; -import org.eclipse.jetty.server.NCSARequestLog; -import org.eclipse.jetty.server.SecureRequestCustomizer; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.ServerConnector; -import org.eclipse.jetty.server.SslConnectionFactory; +import org.eclipse.jetty.security.ConstraintMapping; +import org.eclipse.jetty.security.ConstraintSecurityHandler; +import org.eclipse.jetty.server.*; import org.eclipse.jetty.server.handler.ContextHandlerCollection; import org.eclipse.jetty.server.handler.RequestLogHandler; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.util.security.Constraint; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.webapp.WebAppContext; import org.glassfish.jersey.servlet.ServletContainer; + import static org.glassfish.jersey.servlet.ServletProperties.JAXRS_APPLICATION_CLASS; import static reactor.netty.Metrics.ACTIVE_CONNECTIONS; import static reactor.netty.Metrics.CONNECTION_PROVIDER_PREFIX; @@ -87,6 +92,7 @@ import static reactor.netty.Metrics.PENDING_CONNECTIONS; import static reactor.netty.Metrics.REMOTE_ADDRESS; import static reactor.netty.Metrics.TOTAL_CONNECTIONS; + import io.micrometer.core.instrument.Measurement; import io.micrometer.core.instrument.Meter; import io.micrometer.core.instrument.Metrics; @@ -94,8 +100,10 @@ import io.micrometer.prometheus.PrometheusConfig; import io.micrometer.prometheus.PrometheusMeterRegistry; import io.micrometer.prometheus.PrometheusRenameFilter; + import java.util.Collections; import java.util.Objects; + import lombok.Data; import lombok.Getter; import lombok.Setter; @@ -301,7 +309,7 @@ public void startAdminInterface() throws Exception { } ContextHandlerCollection contexts = new ContextHandlerCollection(); - adminserver.setHandler(contexts); + adminserver.setHandler(constrainTraceMethod(contexts)); File webUi = new File(basePath, "web/ui"); if (webUi.isDirectory()) { @@ -366,6 +374,34 @@ public void startAdminInterface() throws Exception { } + /** + * Add constrain to disable http TRACE method + * + * @param handler + */ + private Handler constrainTraceMethod(Handler handler) { + Constraint constraint = new Constraint(); + constraint.setAuthenticate(true); + + ConstraintMapping constraintMapping = new ConstraintMapping(); + constraintMapping.setConstraint(constraint); + constraintMapping.setMethod(String.valueOf(HttpMethod.TRACE)); + constraintMapping.setPathSpec("/*"); + + Constraint omissionConstraint = new Constraint(); + ConstraintMapping omissionMapping = new ConstraintMapping(); + omissionMapping.setConstraint(omissionConstraint); + omissionMapping.setMethod("*"); + omissionMapping.setPathSpec("/"); + + ConstraintSecurityHandler securityHandler = new ConstraintSecurityHandler(); + securityHandler.addConstraintMapping(constraintMapping); + securityHandler.addConstraintMapping(omissionMapping); + + securityHandler.setHandler(handler); + return securityHandler; + } + public void start() throws InterruptedException, ConfigurationNotValidException { try { started = true; diff --git a/carapace-server/src/test/java/org/carapaceproxy/core/JettyHttpTraceMethodTest.java b/carapace-server/src/test/java/org/carapaceproxy/core/JettyHttpTraceMethodTest.java new file mode 100644 index 000000000..892b7d70c --- /dev/null +++ b/carapace-server/src/test/java/org/carapaceproxy/core/JettyHttpTraceMethodTest.java @@ -0,0 +1,25 @@ +package org.carapaceproxy.core; + +import io.netty.handler.codec.http.HttpMethod; +import org.carapaceproxy.api.UseAdminServer; +import org.junit.Test; + +import javax.servlet.http.HttpServletResponse; +import java.net.HttpURLConnection; +import java.net.URL; + +import static org.junit.Assert.assertEquals; + +public class JettyHttpTraceMethodTest extends UseAdminServer { + + @Test + public void httpTraceMethodTest() throws Exception { + startAdmin(); + String URL = "http://localhost:8761"; + URL url = new URL(URL); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod(String.valueOf(HttpMethod.TRACE)); + int code = conn.getResponseCode(); + assertEquals(HttpServletResponse.SC_FORBIDDEN, code); + } +}