-
Notifications
You must be signed in to change notification settings - Fork 28.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SPARK-20393][Webu UI] Strengthen Spark to prevent XSS vulnerabilities #17686
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is probably fine, but, is this all the calls to request.getParameter? and how real is the threat vs theoretical? anyone who can access Spark can already run arbitrary code on the cluster.
strippedXSSUrl | ||
} | ||
|
||
def stripXSSMap(url: Array[String]): Array[String] = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure what this method is trying to do but it just returns its argument. Do you just mean url.map(stripXSS)
? why Map, why url as names?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I appreciate the feedback. The method returned the array of strings stripped of possible XSS issues. I have used your recommendation in the next commit. Map was changed to Array. url is now requestParameter.
@@ -220,18 +220,20 @@ private[ui] class AllJobsPage(parent: JobsTab) extends WebUIPage("") { | |||
jobTag: String, | |||
jobs: Seq[JobUIData], | |||
killEnabled: Boolean): Seq[Node] = { | |||
val allParameters = request.getParameterMap.asScala.toMap | |||
//stripXSS is called to remove suspicious characters used in XSS attacks | |||
val allParameters = request.getParameterMap.asScala.toMap.mapValues(UIUtils.stripXSSMap(_)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(_)
is redundant here
@@ -220,18 +220,20 @@ private[ui] class AllJobsPage(parent: JobsTab) extends WebUIPage("") { | |||
jobTag: String, | |||
jobs: Seq[JobUIData], | |||
killEnabled: Boolean): Seq[Node] = { | |||
val allParameters = request.getParameterMap.asScala.toMap | |||
// stripXSS is called to remove suspicious characters used in XSS attacks | |||
val allParameters = request.getParameterMap.asScala.toMap.mapValues(UIUtils.stripXSSArray(_)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: omit (_)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed.
* https://www.owasp.org/index.php/Testing_for_Reflected_Cross_site_scripting_(OTG-INPVAL-001) | ||
*/ | ||
def stripXSS(requestParameter: String): String = { | ||
var requestParameterStripped = requestParameter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the body is simpler as
if (requestParameter == null) {
null
} else {
StringEscapeUtils.escapeHtml4(
requestParameter.replaceAll("(\r\n|\n|\r|%0D%0A|%0A|%0D|'|%27)", ""))
}
I'm not sure if it will matter for performance but you could pull out the regex as a saved instance variable instead of compiling it each time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Followed your suggestion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are all the calls to request.getParameter
or similar methods right?
|
||
/** Utility functions for generating XML pages with spark content. */ | ||
private[spark] object UIUtils extends Logging { | ||
val TABLE_CLASS_NOT_STRIPED = "table table-bordered table-condensed" | ||
val TABLE_CLASS_STRIPED = TABLE_CLASS_NOT_STRIPED + " table-striped" | ||
val TABLE_CLASS_STRIPED_SORTABLE = TABLE_CLASS_STRIPED + " sortable" | ||
|
||
val NEWLINE_AND_SINGLE_QUOTE_REGEX = "(\r\n|\n|\r|%0D%0A|%0A|%0D|'|%27)" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is just a string constant rather than regex (with "...".r
). If you're going to do it you can make this faster by reusing the Regex object. (Can these members be private while you're at it?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I intended to make it a regex object; but I did miss the .r; By making these members private are you referring to all of the: TABLE_*?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
replaceAll requires (String, String) so I got a compile error with the regex object.
requestParameter.replaceAll(NEWLINE_AND_SINGLE_QUOTE_REGEX, "")) | ||
} | ||
|
||
def stripXSSArray(requestParameter: Array[String]): Array[String] = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm on the fence about whether it's worth including this as you can just write _.map(stripXSS)
in the two places it's used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll check this again; I had a problem with _.map(stripXSS) compiling; but maybe I did something wrong with it.
And in regards to all the calls; I checked for any type of getParameter call; and also looked for HttpServletRequest with other types of calls. Doesn't appear to be any I missed.
* https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet and | ||
* https://www.owasp.org/index.php/Testing_for_Reflected_Cross_site_scripting_(OTG-INPVAL-001) | ||
*/ | ||
def stripXSS(requestParameter: String): String = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you would, add a couple brief tests of this to UIUtilsSuite
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll work on some.
|
||
/** Utility functions for generating XML pages with spark content. */ | ||
private[spark] object UIUtils extends Logging { | ||
val TABLE_CLASS_NOT_STRIPED = "table table-bordered table-condensed" | ||
val TABLE_CLASS_STRIPED = TABLE_CLASS_NOT_STRIPED + " table-striped" | ||
val TABLE_CLASS_STRIPED_SORTABLE = TABLE_CLASS_STRIPED + " sortable" | ||
|
||
private val NEWLINE_AND_SINGLE_QUOTE_REGEX = "(\r\n|\n|\r|%0D%0A|%0A|%0D|'|%27)" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still think it's worth making this a regex object if you're going to bother, but otherwise LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will attempt. Thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regex created. Changed replaceAll string method to replaceAllIn regex method. Added new test case for new line in parameter.
… for newline in parameter.
Test build #3688 has finished for PR 17686 at commit
|
Test build #3694 has finished for PR 17686 at commit
|
@n-marion looks like still some style issues from the checker |
Missed the import organization. Just ran it locally. Didn't hit same problem. |
Test build #3702 has finished for PR 17686 at commit
|
Adjusted test-case to shorten string. Rerunning to verify passing as well as scalastyle pass for tests. |
Test build #3704 has finished for PR 17686 at commit
|
Merged to master/2.2/2.1 |
## What changes were proposed in this pull request? Add stripXSS and stripXSSMap to Spark Core's UIUtils. Calling these functions at any point that getParameter is called against a HttpServletRequest. ## How was this patch tested? Unit tests, IBM Security AppScan Standard no longer showing vulnerabilities, manual verification of WebUI pages. Author: NICHOLAS T. MARION <nmarion@us.ibm.com> Closes apache#17686 from n-marion/xss-fix.
## What changes were proposed in this pull request? Add stripXSS and stripXSSMap to Spark Core's UIUtils. Calling these functions at any point that getParameter is called against a HttpServletRequest. ## How was this patch tested? Unit tests, IBM Security AppScan Standard no longer showing vulnerabilities, manual verification of WebUI pages. Author: NICHOLAS T. MARION <nmarion@us.ibm.com> Closes #17686 from n-marion/xss-fix. (cherry picked from commit b512233) Signed-off-by: Sean Owen <sowen@cloudera.com>
Add stripXSS and stripXSSMap to Spark Core's UIUtils. Calling these functions at any point that getParameter is called against a HttpServletRequest. Unit tests, IBM Security AppScan Standard no longer showing vulnerabilities, manual verification of WebUI pages. Author: NICHOLAS T. MARION <nmarion@us.ibm.com> Closes #17686 from n-marion/xss-fix. (cherry picked from commit b512233) Signed-off-by: Sean Owen <sowen@cloudera.com>
Add stripXSS and stripXSSMap to Spark Core's UIUtils. Calling these functions at any point that getParameter is called against a HttpServletRequest. Unit tests, IBM Security AppScan Standard no longer showing vulnerabilities, manual verification of WebUI pages. Author: NICHOLAS T. MARION <nmarion@us.ibm.com> Closes apache#17686 from n-marion/xss-fix.
What changes were proposed in this pull request?
Add stripXSS and stripXSSMap to Spark Core's UIUtils. Calling these functions at any point that getParameter is called against a HttpServletRequest.
How was this patch tested?
Unit tests, IBM Security AppScan Standard no longer showing vulnerabilities, manual verification of WebUI pages.