This is an automated email from the ASF dual-hosted git repository.

dongjoon pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/spark.git


The following commit(s) were added to refs/heads/master by this push:
     new bc7c76d8308f [SPARK-54563][UI][TEST] Add test to ensure Jetty 
sanitizes newlines in X-Frame-Options header
bc7c76d8308f is described below

commit bc7c76d8308ffa11434e7cdf0d7b918208cd4d43
Author: Yicong-Huang <[email protected]>
AuthorDate: Thu Dec 4 18:56:49 2025 -0800

    [SPARK-54563][UI][TEST] Add test to ensure Jetty sanitizes newlines in 
X-Frame-Options header
    
    ### What changes were proposed in this pull request?
    
    This PR adds a test to ensure that Jetty sanitizes newlines in the 
`X-Frame-Options` HTTP header, preventing HTTP header injection attacks. The 
test verifies that when `spark.ui.allowFramingFrom` contains newline characters 
(which could occur if someone bypasses config validation), Jetty automatically 
sanitizes them by replacing newlines with spaces.
    
    ### Why are the changes needed?
    
    This test ensures defense-in-depth by verifying that Jetty (the underlying 
HTTP server) also sanitizes newlines in HTTP headers. This protects against 
scenarios where:
    - Configuration validation is bypassed (e.g., through direct property 
setting)
    - Future changes might inadvertently allow newlines
    - Other code paths set the header value
    
    ### Does this PR introduce _any_ user-facing change?
    
    No, this PR only adds a test case. It does not change any user-facing 
behavior.
    
    ### How was this patch tested?
    
    Added a new test
    
    ### Was this patch authored or co-authored using generative AI tooling?
    
    No
    
    Closes #53267
    
    Closes #53331 from 
Yicong-Huang/SPARK-54563/followup/add-test-for-jetty-sanitize-newlines.
    
    Authored-by: Yicong-Huang <[email protected]>
    Signed-off-by: Dongjoon Hyun <[email protected]>
---
 .../test/scala/org/apache/spark/ui/UISuite.scala   | 31 ++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/core/src/test/scala/org/apache/spark/ui/UISuite.scala 
b/core/src/test/scala/org/apache/spark/ui/UISuite.scala
index 6d12e88e8efa..a10060474caa 100644
--- a/core/src/test/scala/org/apache/spark/ui/UISuite.scala
+++ b/core/src/test/scala/org/apache/spark/ui/UISuite.scala
@@ -463,6 +463,37 @@ class UISuite extends SparkFunSuite {
     }
   }
 
+  test("SPARK-54563: Jetty sanitizes newlines in X-Frame-Options header") {
+    val valueWithNewlines = "example.com\nmalicious\nheader"
+    val (conf, securityMgr, sslOptions) = sslDisabledConf()
+    // Set the config value directly to bypass validation, simulating what 
could happen
+    // if someone bypasses the config validation (e.g., through direct 
property setting)
+    conf.set("spark.ui.allowFramingFrom", valueWithNewlines)
+
+    val serverInfo = JettyUtils.startJettyServer("0.0.0.0", 0, sslOptions, 
conf)
+    try {
+      val (_, ctx) = newContext("/test")
+      serverInfo.addHandler(ctx, securityMgr)
+
+      val url = new 
URI(s"http://$localhost:${serverInfo.boundPort}/test/root";).toURL
+      TestUtils.withHttpConnection(url) { conn =>
+        val xFrameOptions = conn.getHeaderField("X-Frame-Options")
+        // Jetty should sanitize newlines by replacing them with spaces
+        assert(xFrameOptions !== null, "X-Frame-Options header should be 
present")
+        assert(!xFrameOptions.contains("\n"),
+          "X-Frame-Options header should not contain newlines")
+        assert(!xFrameOptions.contains("\r"),
+          "X-Frame-Options header should not contain carriage returns")
+        // The header value should have newlines replaced with spaces
+        val expectedValue = "ALLOW-FROM " + 
valueWithNewlines.replaceAll("[\r\n]+", " ")
+        assert(xFrameOptions === expectedValue,
+          s"X-Frame-Options header should have newlines replaced with spaces")
+      }
+    } finally {
+      stopServer(serverInfo)
+    }
+  }
+
   /**
    * Create a new context handler for the given path, with a single servlet 
that responds to
    * requests in `$path/root`.


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

Reply via email to