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 fea5481  [SPARK-55192] Improve HTTP response security
fea5481 is described below

commit fea548118dc4e7daf192595e20cebd8fd5bc12c3
Author: Dongjoon Hyun <[email protected]>
AuthorDate: Mon Jan 26 16:58:07 2026 +0900

    [SPARK-55192] Improve HTTP response security
    
    ### What changes were proposed in this pull request?
    
    This PR aims to improve HTTP response security like Apache Spark.
    - https://github.com/apache/spark/pull/19419
    
    ### Why are the changes needed?
    
    To improve HTTP response by
    
    1. Adding an explicit default handler to generate the response consistently 
like (2).
    2. Adding a set of default headers.
        - Use `text/plain` instead of `text/html` for `Content-Type`
        - Disable cache by `Cache-control: no-cache, no-store, must-revalidate`
        - Disable sniffing by `X-content-type-options: nosniff`
        - Disable resource loading by `Content-security-policy: default-src 
'none'`
    
    **BEFORE**
    
    ```
    $ curl -vv http://localhost:19091/
    * Host localhost:19091 was resolved.
    * IPv6: ::1
    * IPv4: 127.0.0.1
    *   Trying [::1]:19091...
    * Connected to localhost (::1) port 19091
    > GET / HTTP/1.1
    > Host: localhost:19091
    > User-Agent: curl/8.7.1
    > Accept: */*
    >
    * Request completely sent off
    < HTTP/1.1 404 Not Found
    < Content-Length: 50
    < Content-Type: text/html
    < Connection: close
    <
    * Closing connection
    <h1>404 Not Found</h1>No context found for request%
    ```
    
    **AFTER**
    
    ```
    $ curl -vv http://localhost:19091/
    * Host localhost:19091 was resolved.
    * IPv6: ::1
    * IPv4: 127.0.0.1
    *   Trying [::1]:19091...
    * Connected to localhost (::1) port 19091
    > GET / HTTP/1.1
    > Host: localhost:19091
    > User-Agent: curl/8.7.1
    > Accept: */*
    >
    * Request completely sent off
    < HTTP/1.1 404 Not Found
    < X-frame-options: DENY
    < Date: Mon, 26 Jan 2026 07:32:29 GMT
    < Content-security-policy: default-src 'none'
    < Transfer-encoding: chunked
    < Content-type: text/plain; charset=utf-8
    < X-content-type-options: nosniff
    < Cache-control: no-cache, no-store, must-revalidate
    <
    * Connection #0 to host localhost left intact
    ```
    
    ### Does this PR introduce _any_ user-facing change?
    
    No behavior change excepts the read-only HTTP responses.
    
    ### How was this patch tested?
    
    Manual review.
    
    ### Was this patch authored or co-authored using generative AI tooling?
    
    Yes (`Opus 4.5` on `Claude Code v2.1.5`)
    
    Closes #472 from dongjoon-hyun/SPARK-55192.
    
    Authored-by: Dongjoon Hyun <[email protected]>
    Signed-off-by: Dongjoon Hyun <[email protected]>
---
 .../spark/k8s/operator/metrics/PrometheusPullModelHandler.java    | 4 ++--
 .../java/org/apache/spark/k8s/operator/probe/ProbeService.java    | 8 ++++++++
 .../main/java/org/apache/spark/k8s/operator/utils/ProbeUtil.java  | 8 +++++++-
 3 files changed, 17 insertions(+), 3 deletions(-)

diff --git 
a/spark-operator/src/main/java/org/apache/spark/k8s/operator/metrics/PrometheusPullModelHandler.java
 
b/spark-operator/src/main/java/org/apache/spark/k8s/operator/metrics/PrometheusPullModelHandler.java
index 8b723ed..6442d7f 100644
--- 
a/spark-operator/src/main/java/org/apache/spark/k8s/operator/metrics/PrometheusPullModelHandler.java
+++ 
b/spark-operator/src/main/java/org/apache/spark/k8s/operator/metrics/PrometheusPullModelHandler.java
@@ -93,7 +93,7 @@ public class PrometheusPullModelHandler extends 
PrometheusServlet implements Htt
           exchange,
           HTTP_OK,
           formatMetricsSnapshot(),
-          Map.of("Content-Type", List.of("text/plain;version=0.0.4")));
+          Map.of("Content-Type", List.of("text/plain; charset=utf-8; 
version=0.0.4")));
     } else {
       HttpServletRequest httpServletRequest = null;
       String value = getMetricsSnapshot(httpServletRequest);
@@ -101,7 +101,7 @@ public class PrometheusPullModelHandler extends 
PrometheusServlet implements Htt
           exchange,
           HTTP_OK,
           String.join("\n", filterNonEmptyRecords(value)),
-          Map.of("Content-Type", List.of("text/plain;version=0.0.4")));
+          Map.of("Content-Type", List.of("text/plain; charset=utf-8; 
version=0.0.4")));
     }
   }
 
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 9bcd6bb..0fe00ff 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
@@ -19,7 +19,9 @@
 
 package org.apache.spark.k8s.operator.probe;
 
+import static java.net.HttpURLConnection.HTTP_NOT_FOUND;
 import static 
org.apache.spark.k8s.operator.config.SparkOperatorConf.OPERATOR_PROBE_PORT;
+import static org.apache.spark.k8s.operator.utils.ProbeUtil.sendMessage;
 
 import java.io.IOException;
 import java.net.InetSocketAddress;
@@ -56,6 +58,12 @@ public class ProbeService {
     }
     server.createContext(READYZ, new ReadinessProbe(operators));
     server.createContext(HEALTHZ, new HealthProbe(operators, 
sentinelManagers));
+    server.createContext(
+        "/",
+        exchange -> {
+          sendMessage(exchange, HTTP_NOT_FOUND, "");
+          exchange.close();
+        });
     server.setExecutor(executor);
   }
 
diff --git 
a/spark-operator/src/main/java/org/apache/spark/k8s/operator/utils/ProbeUtil.java
 
b/spark-operator/src/main/java/org/apache/spark/k8s/operator/utils/ProbeUtil.java
index 3677f42..99f0291 100644
--- 
a/spark-operator/src/main/java/org/apache/spark/k8s/operator/utils/ProbeUtil.java
+++ 
b/spark-operator/src/main/java/org/apache/spark/k8s/operator/utils/ProbeUtil.java
@@ -66,8 +66,14 @@ public final class ProbeUtil {
       throws IOException {
     try (OutputStream outputStream = httpExchange.getResponseBody()) {
       byte[] bytes = message.getBytes(StandardCharsets.UTF_8);
+      Headers responseHeaders = httpExchange.getResponseHeaders();
+      responseHeaders.set("Cache-Control", "no-cache, no-store, 
must-revalidate");
+      responseHeaders.set("Content-Security-Policy", "default-src 'none'");
+      responseHeaders.set("Content-Type", "text/plain; charset=utf-8");
+      responseHeaders.set("X-Content-Type-Options", "nosniff");
+      responseHeaders.set("X-Frame-Options", "DENY");
+      // Add any additional headers if provided
       if (headers != null && !headers.isEmpty()) {
-        Headers responseHeaders = httpExchange.getResponseHeaders();
         responseHeaders.putAll(headers);
       }
       httpExchange.sendResponseHeaders(code, bytes.length);


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to