[SPARK-57614][WEBUI] Use CSP frame-ancestors instead of deprecated X-Frame-Options: ALLOW-FROM#56669
[SPARK-57614][WEBUI] Use CSP frame-ancestors instead of deprecated X-Frame-Options: ALLOW-FROM#56669sarutak wants to merge 4 commits into
frame-ancestors instead of deprecated X-Frame-Options: ALLOW-FROM#56669Conversation
|
|
||
| val cspNonce = CspNonce.generate() | ||
| try { | ||
| // SPARK-10589 avoid frame-related click-jacking vulnerability. |
There was a problem hiding this comment.
I believe we can remove this line.
| } else { | ||
| // Even when the full CSP is disabled, set frame-ancestors to enforce | ||
| // the allowFramingFrom setting in browsers that support CSP. | ||
| hres.setHeader("Content-Security-Policy", s"$frameAncestors;") |
There was a problem hiding this comment.
May I ask if there is a way to have this feature without CSP header?
Although I agree with your intention, this looks like a conflict to our CSP config option. CSP header should not be used when the CSP configuration is off. In other words, this is a sub feature of CSP parent configuration.
Even when the full CSP is disabled, set frame-ancestors to enforce the allowFramingFrom setting in browsers that support CSP.
There was a problem hiding this comment.
May I ask if there is a way to have this feature without CSP header?
There is no browser mechanism to allow framing from a specific origin without Content-Security-Policy: frame-ancestors. X-Frame-Options only supports DENY and SAMEORIGIN in modern browsers (ALLOW-FROM is obsolete and ignored).
So we have two options:
-
Emit a minimal CSP header (
frame-ancestorsonly) when CSP is disabled
allowFramingFromworks regardless of CSP config, but it's inconsistent with the CSP toggle. -
No CSP header when CSP is disabled
Consistent with the CSP config, butallowFramingFromonly takes effect whenspark.ui.contentSecurityPolicy.enabled=true. When CSP is disabled,X-Frame-Options: SAMEORIGINis always used regardless of theallowFramingFromvalue.
There was a problem hiding this comment.
spark.ui.contentSecurityPolicy.enabled means (2).
For this new feature, shall we add new sub-config like `spark.ui.contentSecurityPolicy.frameAncestors.enabled' because we need a fallback for this transition.
BTW, while testing 4.2.0, I found that CSP feature is too strong and Spark UIs are still immature. I need to revisit one by one.
|
@sarutak ? Are you targeting this to deliver to Apache Spark 4.2.0? I saw that you put this under SPARK-55556 Improve Security which is resolved for Apache Spark 4.2.0 already. |
@dongjoon-hyun cc: @huaxingao |
|
Thank you for updating. I'm also okay for the targeting 4.2.0 as long as Huaxin allows it. |
dongjoon-hyun
left a comment
There was a problem hiding this comment.
-1 because Content-Security-Policy is exposed still when spark.ui.contentSecurityPolicy.enabled=false.
| s"style-src 'self' 'unsafe-inline'; img-src 'self' data:; " + | ||
| s"object-src 'none'; base-uri 'self'; $frameAncestors;") | ||
| } else { | ||
| hres.setHeader("Content-Security-Policy", s"$frameAncestors;") |
There was a problem hiding this comment.
Well, I don't think this is correct.
|
@dongjoon-hyun If your intent is that no CSP header should be emitted at all when
There is no browser mechanism to allow framing from a specific origin without a CSP header. If we choose design consistency, Which trade-off do you prefer? |
|
Before going further, let's clarify this. Apache Spark configuration namespace is organized in this way. Do you agree with this, @sarutak ?
|
|
I agree with the general principle that when I also understand your intent with the new sub-config: However, |
|
Exactly!
I believe this PR sticks to the legacy behavior when |
805253a to
e732bec
Compare
What changes were proposed in this pull request?
This PR fixes the
spark.ui.allowFramingFromconfiguration to use CSPframe-ancestorsdirective instead of the deprecatedX-Frame-Options: ALLOW-FROM.According to MDN Web Docs:
The fix:
spark.ui.contentSecurityPolicy.enabled=true, uses CSPframe-ancestors 'self' <uri>to enforce theallowFramingFromsettingspark.ui.contentSecurityPolicy.frameAncestors.enabled(defaulttrue) as a sub-config to control whetherframe-ancestorsis included in the CSP header. Can be set tofalseas a fallback ifframe-ancestorscauses issuesX-Frame-Options: SAMEORIGINis usedX-Frame-Options: SAMEORIGINheader before access control checks so that even 403 error responses include clickjacking protectionWhy are the changes needed?
The
spark.ui.allowFramingFromconfig has been non-functional in all modern browsers sinceALLOW-FROMwas obsoleted. Users relying on this setting for embedding Spark UI in iframes from specific origins have no working clickjacking protection. CSPframe-ancestorsis the W3C-recommended replacement.Does this PR introduce any user-facing change?
Yes.
spark.ui.allowFramingFromnow works correctly when CSP is enabled, viaframe-ancestorsspark.ui.allowFramingFromrequiresspark.ui.contentSecurityPolicy.enabled=trueto take effect. When CSP is disabled,X-Frame-Options: SAMEORIGINis always used regardless of theallowFramingFromvaluespark.ui.contentSecurityPolicy.frameAncestors.enabled(defaulttrue) controls whetherframe-ancestorsis included in the CSP headerX-Frame-Optionsheader is alwaysSAMEORIGIN(previously it wasALLOW-FROM <uri>which browsers ignored)How was this patch tested?
HttpSecurityFilterSuiteverify:frame-ancestorscontains the configured URI when CSP is enabledframe-ancestorsexcluded whenframeAncestors.enabled=falseDENYmaps toframe-ancestors 'none'SAMEORIGINmaps toframe-ancestors 'self'X-Frame-Options: SAMEORIGINis always set, even on 403 responsesUISuiteverifies Jetty sanitizes newlines in the CSP headerWas this patch authored or co-authored using generative AI tooling?
Kiro CLI / Claude