We can spoof js alert box on an arbitrary domain for Firefox for Android Nightly
Categories
(Fenix :: General, task)
Tracking
(firefox95 wontfix, firefox96 wontfix, firefox97 fixed)
People
(Reporter: proof131072, Assigned: sebastian)
References
Details
(Keywords: csectype-spoof, reporter-external, sec-low, Whiteboard: [reporter-external] [client-bounty-form] [verif?][post-critsmash-triage][adv-main97+])
Attachments
(6 files)
Test on: https://pwning.click/data302r.php
After you allow to reload the page, you are able to run alert box on arbitrary domain for Firefox Nightly. This works through data: URI 302 redirection.
<?php header("Location: data:text/html;base64,PHNjcmlwdD5mdW5jdGlvbiB5KCl7eD1vcGVuKCdodHRwczovL3d3dy5nb29nbGUuY29tJywnX3RvcCcpLHguZG9jdW1lbnQudGl0bGU9JycseC5kb2N1bWVudC5ib2R5LmlubmVySFRNTD0nPGltZy9zcmM9IiJvbmVycm9yPSJhbGVydCgmcXVvdDt0aGlzIGlzIGZyb20gZ29vZ2xlJnF1b3Q7KSI+PGltZy9zcmM9IiJvbmVycm9yPSJhbGVydCgmcXVvdDt0aGlzIGlzIGZyb20gZ29vZ2xlJnF1b3Q7KSI+PGltZy9zcmM9IiJvbmVycm9yPSJhbGVydCgmcXVvdDt0aGlzIGlzIGZyb20gZ29vZ2xlJnF1b3Q7KSI+J307c2V0VGltZW91dCh5LCAxMCk7Cjwvc2NyaXB0Pg==
", true, 302); ?>
If you just close the browser and reopen or crash the browser from other page, this will work without clicking "Try Again".
Comment 3•3 years ago
|
||
The base64 decoded and prettified:
<script>
function y() {
x = open('https://www.google.com', '_top'),
x.document.title = '',
x.document.body.innerHTML =
'<img/src=\"\"onerror=\"alert("this is from google")\">' +
'<img/src=\"\"onerror=\"alert("this is from google")\">' +
'<img/src=\"\"onerror=\"alert("this is from google")\">'
};
setTimeout(y, 10);
</script>
If you load the data: url directly in desktop Firefox you can see the effect James is going for, but I can't reproduce this using his pwning.click url on Firefox Desktop or Fenix Nightly
Firefox Desktop results:
- URL bar is replaced with "about:blank", empty page
- The tab's title and favicon remain those of the previous page (not great, not terrible)
Firefox for Android (Fenix):
- load https://pwning.click/data302r.php
==> Browser error page "Cannot Complete Request", data: URL in the addressbar, and a big "Try Again" button - Press the big purple button
==>
a. most of the time: blank page with the data URL in the addressbar. reloading does nothing
b. once I got a flash of an alert box too fast to read, and then Google loaded.
I also tried reloading using the menu instead of the big purple button but only reproduced the blank page result. On Android I've tried both Nightly and Release. The one time it sort of worked was on Release, but it was so rare I don't think I'd claim it was "fixed" on Nightly even though I can't reproduce.
Note that if you directly type a data: URL into the address bar you get a different error page: "Invalid Address", and the Try Again button just keeps giving you the same error page.
For me the test URL didn't at all work as a spoof even the one time it sort of worked, since the dialog went by so quickly. Might work better with a domain that loads very slowly? Seems dubious you could use this to say much that's convincing when it gets replaced so quickly.
Apart from the spoofing, we've decided that we won't load top-level content from data:
urls, not even if you type it in (unlike desktop where it's easier to type and we've left it as a dev tool for now). But there was at least once where we rendered it. What kind of timing hole could lead to that?
oh, speaking of "timing hole", I should mention that my phone is only a couple months old and is pretty fast. Maybe this is more reproducible on older/slower devices
I tested on latest S21 which loads fast and this is how it looks when I tested.
Comment 6•3 years ago
|
||
Agi: are you able to reproduce the results shown in the attached movie with the testcase https://pwning.click/data302r.php ?
Comment 7•3 years ago
|
||
My experience is the same as Comment 3 on my S10. I think we did a change at some point to dismiss any prompt upon navigation so that might be why we can't reproduce, James what version of Fenix are you on?
cc csadilek because I think he was involved in the prompt fix.
Comment 8•3 years ago
|
||
On my Pixel 2, I can reproduce intermittently and sometimes see the alert after hitting try again. Agree with Daniel, that there's a timing problem involved that still needs investigation.
Assignee | ||
Comment 9•3 years ago
|
||
I can reproduce it too and will investigate the cause.
Assignee | ||
Comment 10•3 years ago
|
||
Okay, there's a lot happening here.
-
I can only reproduce this when hitting "Try again" on the error page, or when this tab gets restored (after a cold start). Sometimes it does not reproduce.
-
We get multiple alerts and they happen before the location change. (Just to be clear: The JS does not seem to have access to the page loaded after) and they stick around.
-
We only keep one reference, for the active prompt. But here multiple alerts are shown quickly. So when we remove the prompt on location change, then there may still be others around that we do not have a reference to anymore. And this is also why this is racing and not always reproducible: If the location change is happening quick enough there may be only one prompt then it gets dismissed. But if there are multiple then only the last one gets dismissed.
To mitigate this we would need to either keep all instances of prompts we create around, so that we can dismiss all of them, or prevent multiple prompts concurrently in the first place, and process them sequentially maybe.
Reporter | ||
Comment 11•3 years ago
|
||
I tested on latest Nightly/Fenix
Reporter | ||
Comment 12•3 years ago
|
||
Reporter | ||
Comment 13•3 years ago
|
||
I could've uploaded better demos for the attack side, so these are 2 cases and the second case could be useful for attackers since we know there are plenty of users who just swipe close the tab and re-open it for most of the time when they see any sort of "error" on their browser. When they do that, it's easy enough for them to confuse that google.com or any other arbitrary generally trusted site is asking for their personal info and/or any type of social engineering attack together from the site as the message of dialog box tells you "This page says~" on https://www.google.com when you load with data: URI instead of "[Origin of the Website] says~" (test e.g. https://pwning.click says) like when you repro this from other site. When the tab gets restored- which is the second case, it works all the time from my testing. While this works on latest devices, we can spoof as many as infinite dialog boxes on arbitrary trusted site for slower (due to many installed apps, etc) and/or old devices.
Assignee | ||
Comment 14•3 years ago
|
||
This patch makes sure we dismiss all dialogs on navigation and not only the last one.
Christian, Arturo and I met yesterday to look at the code. The feature that handles prompts has grown quite a bit over time and is quite complex - and not only handling simple web prompts, but also autofill prompts for logins and credit cards. We have some ideas how this can/should be split up and simplified. But for now we wanted to create a quick fix for this security issue. The result is this patch. We will keep track of all dialog prompts we create and dismiss all of them on navigation.
Assignee | ||
Comment 15•3 years ago
|
||
@Daniel: Can you give us a security severity rating here, so that we can land the patch after review?
Updated•3 years ago
|
Updated•3 years ago
|
Comment 16•3 years ago
|
||
I think long term GeckoView should handle dismissing the prompts in these cases, similar to Bug 1715572
Assignee | ||
Comment 17•3 years ago
|
||
(In reply to Agi Sferro | :agi | ni? for questions | ⏰ PST | he/him from comment #16)
I think long term GeckoView should handle dismissing the prompts in these cases, similar to Bug 1715572
Yeah, that's what we were thinking too and Arturo added it to the agenda for the engineering meeting on Monday. There are multiple things that we "clear/reset" on navigation - trying to emulate what happens internally in Gecko(View). We may want to review all of those cases. Ideally we'd never make such decisions in A-C.
Comment 18•3 years ago
|
||
It's hard to imagine you could say much in a prompt over some other site that would be dangerously convincing. Given your description of the problem in comment 10 I'm assuming that even if the PoC were changed to prompt("Please enter your password to continue")
there is not longer an attacker's page to return the answer to?
Assignee | ||
Comment 19•3 years ago
|
||
Reporter | ||
Comment 20•3 years ago
|
||
(In reply to Daniel Veditz [:dveditz] from comment #18)
It's hard to imagine you could say much in a prompt over some other site that would be dangerously convincing. Given your description of the problem in comment 10 I'm assuming that even if the PoC were changed to
prompt("Please enter your password to continue")
there is not longer an attacker's page to return the answer to?
U can do that by running script from the attacker's site instead of data: URI.
Assignee | ||
Comment 21•3 years ago
|
||
Patch landed 2 weeks ago in 97.0 Nightly.
Updated•3 years ago
|
Reporter | ||
Comment 22•3 years ago
|
||
since we can receive typed info via prompt from users in some case this looks more like moderate imo
Updated•3 years ago
|
Comment 23•3 years ago
|
||
I tested the issue on a OnePlus 6T(Android 9) and Google Pixel 6(Android 12) using the latest Firefox Preview Nightly 97.0a1 2022-01-10.
After accessing the site https://pwning.click/data302r.php and tapping on the Try Again button or reloading the page the https://www.google.com/ webpage is loaded.
Comment 24•3 years ago
|
||
Updated•3 years ago
|
Updated•3 years ago
|
Comment 25•3 years ago
|
||
Updated•3 years ago
|
Updated•2 years ago
|
Updated•2 years ago
|
Updated•8 months ago
|
Description
•