You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spark.apache.org by ho...@apache.org on 2026/09/25 19:20:55 UTC
(spark) branch branch-4.1 updated: [SPARK-59334][CORE] Handle invalid application/worker links
This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a commit to branch branch-4.1
in repository https://gitbox.apache.org/repos/asf/spark.git
The following commit(s) were added to refs/heads/branch-4.1 by this push:
new 69279f94a897 [SPARK-59334][CORE] Handle invalid application/worker links
69279f94a897 is described below
commit 69279f94a89789a34b0b61464601f59ef054c5f1
Author: Holden Karau <ho...@snowflake.com>
AuthorDate: Fri Sep 25 12:19:59 2026 -0700
[SPARK-59334][CORE] Handle invalid application/worker links
Drop invalid links rather than break rendering
Application and worker UI addresses come from external registrants and could contain bad/invalid info. Filter it out to prevent the UI from breaking.
No
New UIUtilSuite test
Yes
Generated-by: Cursor (Kimi K3)
Closes #58622 from holdenk/improve-ui-link-rendering-part2.
Lead-authored-by: Holden Karau <ho...@pigscanfly.ca>
Co-authored-by: Holden Karau <ho...@snowflake.com>
Signed-off-by: Holden Karau <ho...@snowflake.com>
(cherry picked from commit e91d22d3247be55fed37940e32d91c0afc0ab682)
Signed-off-by: Holden Karau <ho...@snowflake.com>
---
core/src/main/scala/org/apache/spark/ui/UIUtils.scala | 18 ++++++++++++++++--
.../test/scala/org/apache/spark/ui/UIUtilsSuite.scala | 14 ++++++++++++++
2 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/core/src/main/scala/org/apache/spark/ui/UIUtils.scala b/core/src/main/scala/org/apache/spark/ui/UIUtils.scala
index 71e3356eda20..bc78f0b96110 100644
--- a/core/src/main/scala/org/apache/spark/ui/UIUtils.scala
+++ b/core/src/main/scala/org/apache/spark/ui/UIUtils.scala
@@ -19,7 +19,7 @@ package org.apache.spark.ui
import java.{util => ju}
import java.lang.{Long => JLong}
-import java.net.{URLDecoder, URLEncoder}
+import java.net.{URI, URISyntaxException, URLDecoder, URLEncoder}
import java.nio.charset.StandardCharsets.UTF_8
import java.time.{Instant, ZoneId}
import java.time.format.DateTimeFormatter
@@ -689,8 +689,22 @@ private[spark] object UIUtils extends Logging {
if (proxy) {
val proxyPrefix = sys.props.getOrElse("spark.ui.proxyBase", "")
proxyPrefix + "/proxy/" + id
- } else {
+ } else if (isSafeHref(origHref)) {
origHref
+ } else {
+ // The href may come from an external registrant (e.g. an application's appUiUrl or
+ // a worker's webUiAddress); render anything unrecognized as a dead link.
+ "#"
+ }
+ }
+
+ /** Returns true if the given href is relative or uses the http(s) scheme. */
+ private def isSafeHref(href: String): Boolean = href != null && {
+ try {
+ val scheme = new URI(href).getScheme
+ scheme == null || scheme.equalsIgnoreCase("http") || scheme.equalsIgnoreCase("https")
+ } catch {
+ case _: URISyntaxException => false
}
}
diff --git a/core/src/test/scala/org/apache/spark/ui/UIUtilsSuite.scala b/core/src/test/scala/org/apache/spark/ui/UIUtilsSuite.scala
index a677f19f5439..1cf7389d011d 100644
--- a/core/src/test/scala/org/apache/spark/ui/UIUtilsSuite.scala
+++ b/core/src/test/scala/org/apache/spark/ui/UIUtilsSuite.scala
@@ -225,4 +225,18 @@ class UIUtilsSuite extends SparkFunSuite {
assert(cell4 === <td>{"java.lang.RuntimeException"}{UIUtils.detailsUINode(isMultiline = true, e4)}</td>)
}
// scalastyle:on line.size.limit
+
+ test("makeHref only renders http(s) or relative URLs as hyperlinks") {
+ // appUiUrl and webUiAddress come from external registrants.
+ assert(UIUtils.makeHref(proxy = false, "app-1", "http://host:4040") === "http://host:4040")
+ assert(UIUtils.makeHref(proxy = false, "app-1", "https://host:4040") === "https://host:4040")
+ assert(UIUtils.makeHref(proxy = false, "app-1", "/relative/path") === "/relative/path")
+ assert(UIUtils.makeHref(proxy = false, "app-1", null) === "#")
+ // A non-http(s) scheme or a malformed URI renders as a dead link.
+ assert(UIUtils.makeHref(proxy = false, "app-1", "javascript:alert(1)") === "#")
+ assert(UIUtils.makeHref(proxy = false, "app-1", "ht tp://bad url") === "#")
+ assert(UIUtils.makeHref(proxy = false, "app-1", "http://host:4040/a b") === "#")
+ // Reverse-proxy mode is unaffected: the href is generated by the master itself.
+ assert(UIUtils.makeHref(proxy = true, "app-1", "javascript:alert(1)").endsWith("/proxy/app-1"))
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@spark.apache.org
For additional commands, e-mail: commits-help@spark.apache.org