fix XSS vulnerability in scaladoc search by escaping the input parameter#8018
fix XSS vulnerability in scaladoc search by escaping the input parameter#8018lrytz merged 3 commits intoscala:2.12.xfrom
Conversation
to trigger XSS vuln, simply paste this into the search bar:
```
"\><img/src='1'onerror=alert(777111)>{{7*7}}
```
all credit for finding the vulnerability goes to *Yeasir Arafat* <skylinearafat@gmail.com>
|
I think they mean "in due time", not "in time for" anything particular. This isn't really XSS, is it? If you paste some sketchy code into your own browser, that's on you. If there were a way to get a specific scaladoc page to then serve that to other people, that would be a problem. It's better to escape now, though, while we still can. 👍 Expanding: this shows a (potential) bug in scaladoc: you cannot cause the xss with a direct link: never manages to inject that code. Has it been long enough that we can use the history API rather than sticking the search string into the URL? |
This is not about the input field in the html, but about how the input parameter is handled. An attacker could send the victim a link like |
|
Sorry, I edited instead of posting a new comment. I'm not arguing against this change; I'm simply pointing out that it doesn't appear to be an actual vulnerability affecting scaladoc sites out there right now, unless there's a different attack vector I hadn't thought of. |
|
Also, I hate to be a nitpicker, but now I can't search for |
|
And to prove I'm not just a naysayer, may I suggest: diff --git a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.js b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.js
index e899f06b5c..84004ef468 100644
--- a/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.js
+++ b/src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.js
@@ -532,7 +532,6 @@ function searchAll() {
scheduler.clear("search"); // clear previous search
maxJobs = 1; // clear previous max
var searchStr = $("#textfilter input").attr("value").trim() || '';
- searchStr = escape(searchStr);
if (searchStr === '') {
$("div#search-results").hide();
@@ -562,10 +561,11 @@ function searchAll() {
entityH1.innerHTML = "Entity results";
entityResults.appendChild(entityH1);
- $("div#results-content")
- .prepend("<span class='search-text'>"
- +" Showing results for <span class='query-str'>\"" + searchStr + "\"</span>"
- +"</span>");
+ var searchTextEl = $("<span class='search-text'>"
+ +" Showing results for <span class='query-str' />"
+ +"</span>");
+ searchTextEl.find(".query-str").text(searchStr);
+ $("div#results-content").prepend(searchTextEl); |
|
I would personally be inclined to never create the tag with any contents using jQuery (or anything else, for that matter) - always setting the text outside of the tag means you will never be able to accidentally open yourself up to injection. In this case I would do one of the following (even though it's slightly more verbose): $("div#results-content")
.prepend(
$("<span>", {class: "search-text"})
.append(document.createTextNode(" Showing results for "))
.append($("<span>", {class: "query-str", text: searchStr}))
);$("div#results-content")
.prepend(
$("<span>")
.addClass("search-text")
.append(document.createTextNode(" Showing results for "))
.append($("<span>").addClass("query-str").text(searchStr))
); |
| scheduler.clear("search"); // clear previous search | ||
| maxJobs = 1; // clear previous max | ||
| var searchStr = $("#textfilter input").attr("value").trim() || ''; | ||
| searchStr = escape(searchStr); |
There was a problem hiding this comment.
What about using encodeURIComponent instead? https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/escape
There was a problem hiding this comment.
I don't think this is the correct solution regardless - as pointed about by Harrison, it prevents you from searching for some things (like :+). The problem is that the untrusted string is embedded in a tag creation below.
|
@mpollmeier I tried this in Chrome, FireFox, IE -> nothing. It does work as originally posted, but it is not a realistic attack vector that would warrant any type of change. |
rather than escaping the search string, which breaks the search for e.g. `:+` solution contributed by NthPortal in scala#8018 (comment)
|
Thanks for all the feedback! I updated the PR to use @NthPortal's 2nd solution from #8018 (comment), which IMO is the cleanest approach. |
hrhino
left a comment
There was a problem hiding this comment.
Published the doc site locally; all appears well. I can search for my silly symbolic aliases, and I can't give myself popups, so LGTM.
Thanks!
| $("<span>") | ||
| .addClass("search-text") | ||
| .append(document.createTextNode(" Showing results for ")) | ||
| .append($("<span>").addClass("query-str").text(searchStr)) |
There was a problem hiding this comment.
So that's how it's done. Mine felt like a hack, but it's been so long since I've used jQuery (Ext.js for life!) that I forgot the right way.
There was a problem hiding this comment.
I heavily abused google and the browser console to figure it out
|
Thanks, everyone involved! |
Fixes scala/bug#11513
To trigger the XSS vulnerability, simply paste this into the search bar, e.g. on https://www.scala-lang.org/api/2.12.8/:
All credit for finding the vulnerability goes to Yeasir Arafat:
skylinearafat@gmail.com
https://www.facebook.com/skylinearafat.arafat
n.b. I've targeted 2.12.x because according to https://github.com/scala/scala/blob/2.13.x/CONTRIBUTING.md this will be merged into 2.13.x 'in time'.