Firefox Mobile iOS Full Address Bar Spoof Using Open in New Tab and Javascript: URI
Categories
(Firefox for iOS :: Browser, defect)
Tracking
()
| Tracking | Status | |
|---|---|---|
| fxios | 134 | --- |
People
(Reporter: renwax23, Unassigned)
References
Details
(Keywords: csectype-spoof, reporter-external, sec-moderate, Whiteboard: [client-bounty-form])
Attachments
(6 files)
Hey Firefox Team
When a URL is javascript://google.com/ and we use (Open in New tab) feature in iOS the new tab is opened and the address bar will be google.com, using this bug we can enter a new line (%0a) and execute our script to insert a fake form or anything else want to be displayed inside the page as the URL will be google.com.
- User visits a webpage
- Inside the page we have a link saying open me inside a new tab
- New tap get's opened which is a Javascript URI and our script executes
- The script will change contents of the page to a fake login page
- User will enter his credentials thinking it's on a legitimate origin
POC: https://pwr.wtf/arc/fx.php
Video POC: ScreenRecording_11-25-2024 14-35-53_1.mp4
POC Source Code: https://pwr.wtf/arc/fx.php?source=1
Mitigation: If the URL is not http(s) don't change the address keep it empty or about:blank
Thanks
Renwa
Updated•1 year ago
|
Comment 1•1 year ago
|
||
Matt: I thought on Firefox for iOS we didn't allow top-level javascript urls? Can you test this POC please?
@dveditz Yes testing the POC so far seems to replicate the vulnerability as long as the user specifically long-presses and chooses Open In New Tab (simply tapping the link normally will not show the spoofed address in the URL bar, AFAICS).
@dveditz A few additional notes:
- The Javascript URL is visible in the preview window when long-pressing (before tapping Open in New Tab), however I suspect most users will not pay as much attention to this as they should
- The apple.com domain is spoofed in the URL bar
- The SSL icon is NOT spoofed, however, and correctly shows the page as insecure
Comment 5•1 year ago
|
||
Comment on attachment 9440306 [details]
poc.html
This POC fetches data from https://pwr.wtf that passes to document.write() to create the spoof page, but even if that part fails in the future it's irrelevant to the vulnerability itself.
- we are hiding the scheme which we should NEVER do, but for practical space reasons we allow for http/https—ONLY! I believe this was already reported recently for data: urls but I'm guessing it's the same exact code and not a separate bug.
- javascript: urls are dangerous and often used in scams to get users to hack themselves. On desktop we finally simply blocked users from using them in the URL bar, but on desktop we have the luxury of the Dev Tools console for power users. Users might demand continued support for manually-entered javascript: URLs on iOS browsers given the lack of other tools, but we should block them from being run through a long-press like this.
The second point is much less important than the first because you can do the same kind of thing using just the first point and a data: URL.
Comment 6•1 year ago
|
||
Without spoofing the lock icon, too, we have to limit the severity to sec-moderate.
Comment 7•1 year ago
|
||
Oh, this is not as simple as hiding the scheme all the time. I suspect
- we are parsing the URL without regard to the actual scheme. This is dangerous: each scheme can support an arbitrary syntax defined by that scheme (within minimal restrictions on what characters need to be encoded)
- if it "looks like"
scheme://something.tld/we appear to parse it assuming the hierarchical URL definition, and then treat "something.tld" as the host. But schemes like javascript: and data: don't support hosts; that's not how you should parse them. If we don't specifically know a scheme we should not guess and should treat it as "scheme:opaque-path". - if we get a non-null host from parsing it (with the wrong syntax) then we assume it IS a host, and show that as a host without the scheme. This is bad EVEN IF the scheme does happen to support hierarchical parsing and hosts. It's SUPER BAD if we're getting a "host" from a scheme that doesn't have hosts at all. A web origin is "scheme + host + port" for schemes that support a host; if any of those are different it is not the origin you think it is so we have to ALWAYS show all three. If we're absolutely consistent, browsers can get away with making an exception for the overwhelmingly common http/https web schemes (IF we distinguish between secure and not secure). We cannot do that that for any other scheme. For schemes that don't support a host (or that we don't know) then each URL is a unique origin, same-origin only with itself.
Don't hide the scheme
Don't do anything based on "host" unless the scheme is http or https
Don't show the "open in new tab" menu item for javascript: urls. make people copy it and do that manually. In fact, whitelist the schemes you know we can support safely and only show it for them.
| Reporter | ||
Comment 10•1 year ago
|
||
(In reply to Daniel Veditz [:dveditz] from comment #6)
Without spoofing the lock icon, too, we have to limit the severity to sec-moderate.
The thing is when we redirect to the javascript: URI we don't have lock icon that shows insecure it's just a long URL bar that no way the user can figure out if it's spoofed. Here is the difference between insecure http scheme and my spoof.
IMG_0346.PNG
I don't know the claim The SSL icon is NOT spoofed, however, and correctly shows the page as insecure from #c3 where it come from
Comment 11•1 year ago
|
||
(In reply to Renwa from comment #10)
I don't know the claim
The SSL icon is NOT spoofed, however, and correctly shows the page as insecurefrom#c3where it come from
In testing so far I see the SSL icon and it shows the page as insecure (attached 2 example screenshots). I've tested across a few devices/configurations. It might be that the icon is hidden in some scenarios or that I'm using slightly different repro steps, however.
Also please note that unless you're testing the latest development branch it is also possible that there are recent code changes that may impact the client UI and app behavior. The toolbar and location view on iOS are currently under active development.
Comment 12•1 year ago
|
||
Comment 13•1 year ago
|
||
| Reporter | ||
Comment 14•1 year ago
|
||
Thanks for your comment, I'm using the latest version from the app store and with the default configuration that's weird I don't see any lock icons, may I know how I can get the same results as yours so I could try bypassing that? I'm on 133.0 (47866) iPhone 16 default settings.
Also I just noticed my video POC wasn't uploaded when I sent the report: https://drive.google.com/file/d/1izCg1zRphTWbbgLGU8hVixq0pkwFWKBc/view?usp=sharing
Comment 15•1 year ago
|
||
I believe I see what is causing the discrepancy, we recently rolled out a UI update to the toolbar on iOS, however it is behind an experiment. If the experiment is disabled and you're testing with the "old" toolbar the POC replicates with the SSL icon hidden. It looks like if the experiment is enabled however (and you test with the "new" toolbar) the SSL icon does show insecure correctly. That is at least what I'm seeing consistently when I try switching between the two.
Comment 16•1 year ago
|
||
(In reply to Daniel Veditz [:dveditz] from comment #7)
Oh, this is not as simple as hiding the scheme all the time. I suspect
- we are parsing the URL without regard to the actual scheme. This is dangerous: each scheme can support an arbitrary syntax defined by that scheme (within minimal restrictions on what characters need to be encoded)
- if it "looks like"
scheme://something.tld/we appear to parse it assuming the hierarchical URL definition, and then treat "something.tld" as the host. But schemes like javascript: and data: don't support hosts; that's not how you should parse them. If we don't specifically know a scheme we should not guess and should treat it as "scheme:opaque-path".
@dveditz I'm still digging into this, but to clarify a couple things: our URL bar is displaying the host property of URLComponents which is a foundation class provided by Apple. In other words, the root origin of the actual "apple.com" text in the URL bar is not something we are parsing in a custom way in the iOS client, we are relying on Apple's foundation lib to provide us the host based on the URLComponents that we instantiate from the URL string.
Unfortunately, for URLs starting with something like javascript://www.apple.com, this foundation code simply parses out the domain as it normally would, resulting in the "apple.com" in the URL bar. We can override this logic of course for JS or data schemes, though I'm a bit concerned about us changing one of these fundamental URL functions due to how many different places rely on them in the codebase.
The other challenge is related to the suggestion of "Don't hide the scheme". Unless I'm misunderstanding, I believe changing the current logic (which is based on specs from Design/UX) would be a fairly complicated process where we'd have to loop those teams into the decision making. I suspect we could get away with deviating from the current UI behavior for this security ticket for special-case scenarios such as this one, where the URL is a javascript:// or data:// scheme opened in a new tab (which is not very typical). However I'm not entirely clear if that fully satisfies the concerns that you discussed above.
To try to summarize all of this:
- Preventing the JS links from being opened directly in a new tab (on long press) is easy, and can be fixed quickly
- Changing the URL parsing code, however, is delicate and I'm a bit concerned about the inherent risks of side effects with that
- Similarly, changes to the UI behavior (e.g. un-hiding the scheme in the URL bar) may be complicated due to requiring sign-off from Design/UX
Ultimately, I can't actually see any practical way for this attack to be leveraged OTHER than the open-in-new-tab flow. For example, even pasting in the javascript:// URL directly currently does not appear to work in Firefox iOS (I haven't been able to get it to work in testing). And clicking the link directly in a malicious page does not show the spoofed host/domain. AFAICS for the spoof attack to work, you must specifically long press + open-in-new-tab.
If the above is correct, then I'd suggest that for now we make the minimal change necessary which is to simply prevent javascript:// URLs from being opened in a new tab via the long-press.
@dveditz Can you let me know if I'm missing anything critical (or misunderstanding)?
| Reporter | ||
Comment 17•1 year ago
|
||
| Reporter | ||
Comment 18•1 year ago
|
||
I still don't see the lock icon indicator in latest public update 133.3 (today's update), when this experiment new toolbar will be released and I can access it? I want to look at a way bypassing the indicator and showing a secure origin to get the severity to high.
Comment 19•1 year ago
|
||
Comment 20•1 year ago
|
||
This is still pending QA validation, however given that it was confirmed by engineering I'm going to move to Resolved. I've pinged QA again and will update if there are any further issues raised.
Comment 21•1 year ago
|
||
Updated•1 year ago
|
Updated•1 year ago
|
Updated•1 year ago
|
Updated•1 year ago
|
Updated•1 year ago
|
Updated•1 year ago
|
Updated•1 month ago
|
Description
•