This is an automated email from the ASF dual-hosted git repository.
dongjoon pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/spark-kubernetes-operator.git
The following commit(s) were added to refs/heads/main by this push:
new 2c48595 [SPARK-55270] Disallow all HTTP methods except `GET` and
`HEAD`
2c48595 is described below
commit 2c48595fd9dee8c9a85bf6dc9940626ba4b633d3
Author: Dongjoon Hyun <[email protected]>
AuthorDate: Thu Jan 29 17:19:10 2026 +0900
[SPARK-55270] Disallow all HTTP methods except `GET` and `HEAD`
### What changes were proposed in this pull request?
This PR aims to disallow all HTTP methods except `GET` and `HEAD` method.
### Why are the changes needed?
Like Apache Spark Web UI, we had better response the exact HTTP requests.
In `Apache Spark K8s Operator` operator, `GET` and `HEAD` is the only allowed
method and other methods like `POST`, `PUT`, `POST`, `DELETE`, `TRACE`, and
`OPTIONS` will be denied.
- https://github.com/apache/spark/pull/4765
- https://github.com/apache/spark/pull/44926
### Does this PR introduce _any_ user-facing change?
Yes for the security improvement.
### How was this patch tested?
Pass the CIs.
**BEFORE**
```
$ curl -s -I -XPOST http://localhost:19091/healthz | head -n1
HTTP/1.1 200 OK
```
**AFTER**
```
$ curl -s -I -XPOST http://localhost:19091/healthz | head -n1
HTTP/1.1 405 Method Not Allowed
```
### Was this patch authored or co-authored using generative AI tooling?
Yes (`Opus 4.5` on `Claude Code v2.1.5`)
Closes #475 from dongjoon-hyun/SPARK-55270.
Authored-by: Dongjoon Hyun <[email protected]>
Signed-off-by: Dongjoon Hyun <[email protected]>
---
.../spark/k8s/operator/metrics/MetricsService.java | 5 ++-
.../spark/k8s/operator/probe/ProbeService.java | 9 ++--
.../spark/k8s/operator/utils/HttpMethodFilter.java | 52 ++++++++++++++++++++++
3 files changed, 62 insertions(+), 4 deletions(-)
diff --git
a/spark-operator/src/main/java/org/apache/spark/k8s/operator/metrics/MetricsService.java
b/spark-operator/src/main/java/org/apache/spark/k8s/operator/metrics/MetricsService.java
index 99e9ced..c3024b5 100644
---
a/spark-operator/src/main/java/org/apache/spark/k8s/operator/metrics/MetricsService.java
+++
b/spark-operator/src/main/java/org/apache/spark/k8s/operator/metrics/MetricsService.java
@@ -28,6 +28,8 @@ import java.util.concurrent.Executor;
import com.sun.net.httpserver.HttpServer;
import lombok.extern.slf4j.Slf4j;
+import org.apache.spark.k8s.operator.utils.HttpMethodFilter;
+
/** Start Http service at endpoint /prometheus, exposing operator metrics. */
@Slf4j
public class MetricsService {
@@ -53,7 +55,8 @@ public class MetricsService {
/** Starts the HTTP server and exposes the Prometheus metrics endpoint. */
public void start() {
log.info("Starting Metrics Service for Prometheus ...");
- server.createContext("/prometheus",
metricsSystem.getPrometheusPullModelHandler());
+ server.createContext("/prometheus",
metricsSystem.getPrometheusPullModelHandler())
+ .getFilters().add(new HttpMethodFilter());
server.start();
}
diff --git
a/spark-operator/src/main/java/org/apache/spark/k8s/operator/probe/ProbeService.java
b/spark-operator/src/main/java/org/apache/spark/k8s/operator/probe/ProbeService.java
index 0fe00ff..c14b0fe 100644
---
a/spark-operator/src/main/java/org/apache/spark/k8s/operator/probe/ProbeService.java
+++
b/spark-operator/src/main/java/org/apache/spark/k8s/operator/probe/ProbeService.java
@@ -34,12 +34,14 @@ import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.spark.k8s.operator.metrics.healthcheck.SentinelManager;
+import org.apache.spark.k8s.operator.utils.HttpMethodFilter;
/** Service for health and readiness probes. */
@Slf4j
public class ProbeService {
public static final String HEALTHZ = "/healthz";
public static final String READYZ = "/readyz";
+ private static final HttpMethodFilter FILTER = new HttpMethodFilter();
@Getter private final HttpServer server;
/**
@@ -56,14 +58,15 @@ public class ProbeService {
} catch (IOException e) {
throw new IllegalStateException("Failed to create Probe Service Server",
e);
}
- server.createContext(READYZ, new ReadinessProbe(operators));
- server.createContext(HEALTHZ, new HealthProbe(operators,
sentinelManagers));
+ server.createContext(READYZ, new
ReadinessProbe(operators)).getFilters().add(FILTER);
+ server.createContext(HEALTHZ, new HealthProbe(operators, sentinelManagers))
+ .getFilters().add(FILTER);
server.createContext(
"/",
exchange -> {
sendMessage(exchange, HTTP_NOT_FOUND, "");
exchange.close();
- });
+ }).getFilters().add(FILTER);
server.setExecutor(executor);
}
diff --git
a/spark-operator/src/main/java/org/apache/spark/k8s/operator/utils/HttpMethodFilter.java
b/spark-operator/src/main/java/org/apache/spark/k8s/operator/utils/HttpMethodFilter.java
new file mode 100644
index 0000000..a5be781
--- /dev/null
+++
b/spark-operator/src/main/java/org/apache/spark/k8s/operator/utils/HttpMethodFilter.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.spark.k8s.operator.utils;
+
+import static java.net.HttpURLConnection.HTTP_BAD_METHOD;
+import static org.apache.spark.k8s.operator.utils.ProbeUtil.sendMessage;
+
+import java.io.IOException;
+import java.util.Set;
+
+import com.sun.net.httpserver.Filter;
+import com.sun.net.httpserver.HttpExchange;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * A filter that only allows GET and HTTP requests and returns 405 Method Not
Allowed for all
+ * other HTTP methods.
+ */
+@Slf4j
+public class HttpMethodFilter extends Filter {
+ @Override
+ public void doFilter(HttpExchange exchange, Chain chain) throws IOException {
+ if (!Set.of("GET",
"HEAD").contains(exchange.getRequestMethod().toUpperCase())) {
+ sendMessage(exchange, HTTP_BAD_METHOD, "Method Not Allowed");
+ exchange.close();
+ return;
+ }
+ chain.doFilter(exchange);
+ }
+
+ @Override
+ public String description() {
+ return "Filter that only allows GET requests";
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]