This is an automated email from the ASF dual-hosted git repository. andor pushed a commit to branch branch-3.8 in repository https://gitbox.apache.org/repos/asf/zookeeper.git
The following commit(s) were added to refs/heads/branch-3.8 by this push: new 54da69219 ZOOKEEPER-3731: Disable HTTP TRACE Method (branch-3.8) 54da69219 is described below commit 54da69219cc0adcc5cecf8e5f755fd93e464a0d5 Author: Andor Molnár <an...@apache.org> AuthorDate: Thu May 22 18:40:10 2025 -0500 ZOOKEEPER-3731: Disable HTTP TRACE Method (branch-3.8) ZOOKEEPER-3731: Disallow HTTP TRACE method on PrometheusMetrics Server (#1682) Author: anmolnar Closes #2262 from anmolnar/ZOOKEEPER-3731_38 --- .../prometheus/PrometheusMetricsProvider.java | 23 +++++++++++++++++++++ .../prometheus/PrometheusMetricsProviderTest.java | 24 ++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/zookeeper-metrics-providers/zookeeper-prometheus-metrics/src/main/java/org/apache/zookeeper/metrics/prometheus/PrometheusMetricsProvider.java b/zookeeper-metrics-providers/zookeeper-prometheus-metrics/src/main/java/org/apache/zookeeper/metrics/prometheus/PrometheusMetricsProvider.java index e17b09785..af4bff9d2 100644 --- a/zookeeper-metrics-providers/zookeeper-prometheus-metrics/src/main/java/org/apache/zookeeper/metrics/prometheus/PrometheusMetricsProvider.java +++ b/zookeeper-metrics-providers/zookeeper-prometheus-metrics/src/main/java/org/apache/zookeeper/metrics/prometheus/PrometheusMetricsProvider.java @@ -52,9 +52,12 @@ import org.apache.zookeeper.metrics.Summary; import org.apache.zookeeper.metrics.SummarySet; import org.apache.zookeeper.server.RateLogger; +import org.eclipse.jetty.security.ConstraintMapping; +import org.eclipse.jetty.security.ConstraintSecurityHandler; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.util.security.Constraint; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -134,6 +137,7 @@ public void start() throws MetricsProviderLifeCycleException { server = new Server(new InetSocketAddress(host, port)); ServletContextHandler context = new ServletContextHandler(); context.setContextPath("/"); + constrainTraceMethod(context); server.setHandler(context); context.addServlet(new ServletHolder(servlet), "/metrics"); server.start(); @@ -235,6 +239,25 @@ public void resetAllValues() { // not supported on Prometheus } + /** + * Add constraint to a given context to disallow TRACE method. + * @param ctxHandler the context to modify + */ + private void constrainTraceMethod(ServletContextHandler ctxHandler) { + Constraint c = new Constraint(); + c.setAuthenticate(true); + + ConstraintMapping cmt = new ConstraintMapping(); + cmt.setConstraint(c); + cmt.setMethod("TRACE"); + cmt.setPathSpec("/*"); + + ConstraintSecurityHandler securityHandler = new ConstraintSecurityHandler(); + securityHandler.setConstraintMappings(new ConstraintMapping[] {cmt}); + + ctxHandler.setSecurityHandler(securityHandler); + } + private class Context implements MetricsContext { private final ConcurrentMap<String, PrometheusGaugeWrapper> gauges = new ConcurrentHashMap<>(); diff --git a/zookeeper-metrics-providers/zookeeper-prometheus-metrics/src/test/java/org/apache/zookeeper/metrics/prometheus/PrometheusMetricsProviderTest.java b/zookeeper-metrics-providers/zookeeper-prometheus-metrics/src/test/java/org/apache/zookeeper/metrics/prometheus/PrometheusMetricsProviderTest.java index 9284f52bb..eb9cf8bd2 100644 --- a/zookeeper-metrics-providers/zookeeper-prometheus-metrics/src/test/java/org/apache/zookeeper/metrics/prometheus/PrometheusMetricsProviderTest.java +++ b/zookeeper-metrics-providers/zookeeper-prometheus-metrics/src/test/java/org/apache/zookeeper/metrics/prometheus/PrometheusMetricsProviderTest.java @@ -31,6 +31,9 @@ import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; +import java.lang.reflect.Field; +import java.net.HttpURLConnection; +import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -50,7 +53,10 @@ import org.apache.zookeeper.metrics.Summary; import org.apache.zookeeper.metrics.SummarySet; import org.apache.zookeeper.server.util.QuotaMetricsUtils; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; import org.hamcrest.CoreMatchers; +import org.junit.Assert; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -61,6 +67,7 @@ */ public class PrometheusMetricsProviderTest { + private static final String URL_FORMAT = "http://localhost:%d/metrics"; private PrometheusMetricsProvider provider; @BeforeEach @@ -395,6 +402,23 @@ public void testAdvancedSummary() throws Exception { assertThat(res, CoreMatchers.containsString("cc{quantile=\"0.99\",} 10.0")); } + /** + * Using TRACE method to visit metrics provider, the response should be 403 forbidden. + */ + @Test + public void testTraceCall() throws IOException, IllegalAccessException, NoSuchFieldException { + Field privateServerField = provider.getClass().getDeclaredField("server"); + privateServerField.setAccessible(true); + Server server = (Server) privateServerField.get(provider); + int port = ((ServerConnector) server.getConnectors()[0]).getLocalPort(); + + String metricsUrl = String.format(URL_FORMAT, port); + HttpURLConnection conn = (HttpURLConnection) new URL(metricsUrl).openConnection(); + conn.setRequestMethod("TRACE"); + conn.connect(); + Assert.assertEquals(HttpURLConnection.HTTP_FORBIDDEN, conn.getResponseCode()); + } + @Test public void testSummary_asyncAndExceedMaxQueueSize() throws Exception { final Properties config = new Properties();