From e04e1140b55282b7940d717237499ba05fbf3935 Mon Sep 17 00:00:00 2001 From: Dongjoon Hyun Date: Fri, 17 Apr 2026 11:10:35 -0700 Subject: [PATCH] [SPARK-56528][CORE] Make Jetty SniHostCheck configurable --- .../scala/org/apache/spark/internal/config/UI.scala | 10 ++++++++++ .../main/scala/org/apache/spark/ui/JettyUtils.scala | 6 ++++-- .../configs-without-binding-policy-exceptions | 1 + 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/org/apache/spark/internal/config/UI.scala b/core/src/main/scala/org/apache/spark/internal/config/UI.scala index 70d42df6520bb..20c99794cd215 100644 --- a/core/src/main/scala/org/apache/spark/internal/config/UI.scala +++ b/core/src/main/scala/org/apache/spark/internal/config/UI.scala @@ -142,6 +142,16 @@ private[spark] object UI { .bytesConf(ByteUnit.BYTE) .createWithDefaultString("8k") + val UI_JETTY_SNI_HOST_CHECK = ConfigBuilder("spark.ui.jetty.sniHostCheckEnabled") + .internal() + .doc("Whether to enable Jetty's SNI host check on the Spark UI HTTPS connector. " + + "Since SPARK-45522 (Jetty 10+), Spark has disabled SNI host check to preserve " + + "backward compatibility with standalone deployments. Set to true to enforce " + + "SNI host checking for stricter security.") + .version("4.2.0") + .booleanConf + .createWithDefault(false) + val UI_TIMELINE_ENABLED = ConfigBuilder("spark.ui.timelineEnabled") .doc("Whether to display event timeline data on UI pages.") .version("3.4.0") diff --git a/core/src/main/scala/org/apache/spark/ui/JettyUtils.scala b/core/src/main/scala/org/apache/spark/ui/JettyUtils.scala index 5a690e6559c5a..3c21fd6d2a003 100644 --- a/core/src/main/scala/org/apache/spark/ui/JettyUtils.scala +++ b/core/src/main/scala/org/apache/spark/ui/JettyUtils.scala @@ -335,9 +335,11 @@ private[spark] object JettyUtils extends Logging { val securePort = sslOptions.createJettySslContextFactoryServer().map { factory => // SPARK-45522: SniHostCheck defaulted to true since Jetty 10, - // this will affect the standalone deployment. + // this will affect the standalone deployment. Exposed via + // spark.ui.jetty.sniHostCheckEnabled so operators can enable + // it when stricter host checking is desired. val src = new SecureRequestCustomizer() - src.setSniHostCheck(false) + src.setSniHostCheck(conf.get(UI_JETTY_SNI_HOST_CHECK)) httpConfig.addCustomizer(src) val securePort = sslOptions.port.getOrElse(if (port > 0) Utils.userPort(port, 400) else 0) diff --git a/sql/hive/src/test/resources/conf/binding-policy-exceptions/configs-without-binding-policy-exceptions b/sql/hive/src/test/resources/conf/binding-policy-exceptions/configs-without-binding-policy-exceptions index ee86a378547f5..4563e81d14064 100644 --- a/sql/hive/src/test/resources/conf/binding-policy-exceptions/configs-without-binding-policy-exceptions +++ b/sql/hive/src/test/resources/conf/binding-policy-exceptions/configs-without-binding-policy-exceptions @@ -1189,6 +1189,7 @@ spark.ui.enabled spark.ui.filters spark.ui.groupSQLSubExecutionEnabled spark.ui.heapHistogramEnabled +spark.ui.jetty.sniHostCheckEnabled spark.ui.jetty.stopTimeout spark.ui.killEnabled spark.ui.liveUpdate.minFlushPeriod