Closed Bug 966532 Opened 7 years ago Closed 5 years ago
Address bar spoofing combined with hidden page replacement
Thank you, Al Billings! I am really sorry for not checking the "security check" before submitting, I don't know what was on my mind. Sorry.
Just noting here that your example script is throwing   Uncaught TypeError: Cannot read property 'location' of null
Hello Aaron, This happens when you click on the link, but the link doesn't open in a new tab, so the window.opener is not set to anything (it really is null). To remake my scenario, pay attention to the following conditions: - the link MUST be opened from a page where the target is set to "_blank", so it will open a new tab; - just left click it (or tap it, if you are using a touch device); it won't work if you right click -> Open in new tab, it won't work if you hold the Ctrl key and left click on the link; In the source code of tab 1, there should be something like <a href="http://daniel-tomescu.com/xyztest.php" target="_blank"> Click me </a> bugzilla.mozilla.org opens links in the same tab, so just by clicking on it from this bug page won't work. Use facebook, twitter, vbulletin forums etc If you have a hard time remaking my scenario, I could make a short video about it... Is it necessary? Sorry for my bad English...
We understood that this sort of tradeoff when making Firefox for Android. This is mostly bug 605206. Bug 778216 is the main mitigation.
I am not sure you've taken into consideration all the security implications of showing the title instead of the URL. In the example I've provided in my initial post, you can see how the user can be tricked by only clicking a link. And this is because everything you show to a user by default can be spoofed by an attacker. I get that it looks "fancy" to show the user the title, but this is wrong from two points of view: - a developer doesn't really care about the webpage title, some sites doesn't even have a title set; developers care more about the domain (and the URL) because that is what users should remember. Remembering the domain name helps users get back on the site, remembering the title doesn't. Just ask a few people if they remember the title or the domain of their favorite payment website, file sharing website or social website. And please note that those are key-types of websites from an attackers point of view; - displaying the title leaves the user clueless in case of being redirected on a scam page. He entered on a legitimate website, manually checked the URL just to be sure, then he clicks on a link (and this is really standard user behavior, can you imagine internet without clicking on links?!?) and when he returns on the initial website he'll have no idea about the security context of the page. What should he do, manually check again the URL? Can you imagine browsing on Android and being forced to manually check the URL every time you switch tabs? I can't... And I'm not talking only about advanced users, I'm taking about teenagers that are always in a hurry, I'm taking about people with little knowledge on security matters, they will never manually check the URL when switching tabs... In the end, the trade resumes about what do you care more about: a fancy feature that is not that important for users and developers, or keeping your users safe?
I agree that this is essentially a dupe of bug 605206. The security implications of not making the URL (or at least: host) obvious have been brought up multiple times by various people as making phishing way easier. What's new in this bug is replacing an existing tab via this trick: window.opener.location.replace('http://daniel-tomescu.com/scam.php'); CCing the UX people to see if this makes them reevaluate 605206.
I'm not convinced this isn't a dupe of bug 605206, but since I was sad to see that wontfixed (for the reasons stated by the reporter here) I can confirm this one. We did add a pref so that users and addons can force the display of the URL instead of the title, but that doesn't help very many people. My main hope there was that enough people would feel this threat that there'd be a popular add-on that made this switch.
I've always been of the mind that there is far greater informational value to showing our users a page title by default, compared to the risk people have raised of not showing a URL. A 'normal' non-technical user (think of the 99% population of non-wizard user types we have) wouldn't have the technical know-how to recognize a spoofed site even if they saw the URL. For the remaining 1% who would, we have an easy to access pref they can flip in Settings. And to build on that, if what Mark is saying in https://bugzilla.mozilla.org/show_bug.cgi?id=605206#c37 is true, that we actually don't even have any evidence that showing a URL has any impact on the phishability of a page, then it's even harder for me to see the value of defaulting to a non-human-readable string (a URL) instead of a human-readable string (a title). I agree that Daniel has identified a security issue here, but it doesn't sound like showing a URL is the thing that will fix it.
I'm not a security expert, but: window.opener.location.replace('http://daniel-tomescu.com/scam.php'); >5. The facebook tab reloads with the scam page, BUT THE VICTIM DOESN'T SEE THIS!!! because the focus is >on the tab containing the decoy page; Should this be even possible? http://stackoverflow.com/questions/8141417/how-to-get-access-from-cross-site-popup-to-window-opener "That sounds like cross-domain scripting which is going to be prevented by security limitations; or am I reading the question incorrectly?" Strangely, it works for me in Firefox. <<<<<<<<
@Ian Barlow, For me, this is very simple, a black and white situation: showing the URL has a security value because the URL is an identifier of the webpage, while showing the title has no security value and can confuse people. Thank you all for your interest in this bug. Maybe we will come up with a solution for this situation because I think we can all agree that the scenario I've presented in my initial post is not normal. So.. thank you for validating the bug!
Easier link for testing POC (reuses reporter links, but has the _blank thing): http://sjeng.org/mozilla/facebook.html Testing on mobile: * Chrome: not vulnerable, always shows URL, Page title only used in tab thumbnail views * Dolphin: not vulnerable, always shows URL, Page title on tabs * Firefox: vulnerable, no way to see that the original page got redirected if you don't click the awesomebar Testing on desktop: * Chrome, Firefox: allow the redirect, but of course show the URL * Internet Explorer: DOES NOT allow the redirect, it pops up a question on the "facebook" page whether a script from "scamsite-domain.com" is allowed to run. So, basically, if we're going to maintain the UX decision that "URLs don't matter because they're too complicated", we should very strongly consider an IE-style doorhanger before allowing this kind of same-origin violation. Related: http://my.opera.com/hallvors/blog/2007/03/14/window-opener-and-security-an-unfixable-problem
I agree we should be doing something about window.opener. Ideally, we could just block it, though Hallvord's blog post indicates that this will break some sites. How big of a problem is that on mobile? If we can't just block the behavior, showing a doorhanger on the tab that is being changed seems appropriate.
(In reply to Ian Barlow (:ibarlow) from comment #8) > I agree that Daniel has identified a security issue here, but it doesn't > sound like showing a URL is the thing that will fix it. Agreed. And if the people in this bug really feel this is a security issue we had better find a solution that does not depend on "show the URL". That helps almost no one.
> How big of a problem is that on mobile? I can't tell you that. What I can tell you is that cross-origin location.replace() is explicitly white-listed in implementation and the spec as being allowed because so many things depend on it. Now they might be depending on it in the "cross-origin subframe" case, not the "cross-origin opener" case.... We could conceivably do something where if we open via target=_blank and the destination URI is not same-origin with us we cut the opener link. We would need to see what other UA vendors think of that.
(In reply to Boris Zbarsky [:bz] from comment #14) > > How big of a problem is that on mobile? > > I can't tell you that. > > What I can tell you is that cross-origin location.replace() is explicitly > white-listed in implementation and the spec as being allowed because so many > things depend on it. Now they might be depending on it in the "cross-origin > subframe" case, not the "cross-origin opener" case.... > > We could conceivably do something where if we open via target=_blank and the > destination URI is not same-origin with us we cut the opener link. We would > need to see what other UA vendors think of that. In the meantime, could we send a notification, with the front-end can catch, so we could notify the user that the tab changed without them knowing it? I don't want to popup notifications anytime a tab changes location, only for this situation.
Hello again, A bit offtopic, but I think it might be helpful: Sites like *.google.com, *.facebook.com, *.twitter.com allow users to open sites in a new tab, but they have a nice pattern: 1. they wrap the URLs to be opened in one of their own, like t.co/something or plus.url.google.com/something; 2. they open the wrapped URL in a new tab; 3. they check if the url contains malware/is blacklisted/ is safe; 4. they redirect the user to the new URL; Google is the only one that actually blocks the window.opener property in step 3. Just pointing out that one of the top companies in the industry has already seen this as a threat.
Can we define "this situation"? Is it a background tab being navigated to a URL that's not same-origin with its current URL? A background tab being navigated via a cross-site replace()/hrefsetter call? Some combination of the two?
A background tab being navigated through an action from a JS file that resides on another domain, which I presume is your second case. What are the cases for the first? An XSS attack that acts and redirects the page the moment it gets backgrounded?
>But consider also a page that opens a popup window that can load cross-domain things. And then you >click a link on that page to navigate the popup window This is a pretty broken use case for mobile to begin with, I think? I don't think we have real popup windows. (Might be Adblock as well :-)
> I don't think we have real popup windows. Right, that's what puts the popup in a background tab.... My point is I would be very surprised if there are no sites out there doing that.
Right, but those provide a bad user experience now, at worst we're making it a little worse. I think we can live with this. The way the IE permission popup works is that it seems to remember that "*.scam-domain-helper.com" is allowed to do the cross-site navigation. With your example that means you'd only need to dismiss the popup once? If the info who (host) requested who (tab) to navigate is available to the Android UI JS then making some "Always allow for host" thingie should be very doable. But maybe mfinkle should comment on that :)
(In reply to Boris Zbarsky [:bz] from comment #19) > > A background tab being navigated through an action from a JS file that resides on another > > domain > > Bobby, do we have the caller principal by the time we land in Location code? You mean nsContentUtils::GetSubjectPrincipal()? Certainly. In the cross-origin case, it'll go over Xrays. There's no difference between Location and any other DOM interface these days, except for the fact that most Location methods do an explicit security check in C++ to deal with the inactive inner case.
Rereading this: >A background tab being navigated via a cross-site replace()/hrefsetter call? ... >A background tab being navigated through an action from a JS file that resides on another domain, which >I presume is your second case. ... >But consider also a page that opens a popup window that can load cross-domain things. And then you >click a link on that page to navigate the popup window I'm thinking the case you mention wouldn't be caught by the rule you mentioned, but it would be by what I mentioned? A page opening a tab and then controlling that tab seems OK to me. It's the reverse that is problematic.
> In the cross-origin case, it'll go over Xrays. That was the part I was verifying: that we can detect the cross-origin case inside C++ here. > I'm thinking the case you mention wouldn't be caught by the rule you mentioned, Actually, it would. > A page opening a tab and then controlling that tab seems OK to me. OK, so what we really need is to somehow tie things back to openers... I'm not quite sure how.
I wouldn't like this to die out in the perfect-is-the-enemy-of-good sense. bz, how hard is it to do the next best thing that might warn in more situations but is simpler to implement? UX, would it be worthwhile to think about displaying the domain instead of the page title, if the domain was changed while the page was backgrounded? This is a) simpler b) doable entirely in Android browser.js - I think - c) defeats this attack. I would still prefer the doorhanger-style notification because it catches people's attention better, but if that turns out to give to many false positives, again, we can try the next best thing.
I'm changing the title to make it clear what we're trying to prevent. UX has made it clear they don't think the address bar is enough to protect most users. Also needinfo bz for previous comment.
Summary: address bar spoofing → Address bar spoofing combined with hidden page replacement
> how hard is it to do the next best thing Which thing is that? What behavior are you aiming for?
The thing described in comment 18/19. I had the impression the caveat I mentioned in comment 24/25 complicated things. Detect when a site that's in the background has it's location changed through cross-site scripting.
18/19 do not describe a "thing". 19 lists several different possible "things", and it's not clear to me which of them we want for this bug.
Can you then explain why they are "different things", and which of those "different things" we can detect without major infrastructure changes or an overly complicated patch, so we can make a judgment if we can likely just live with any false positives they give?
The fundamental question I want to understand is what we're trying to protect against. It seems like we want to protect against certain page navigations when the window being navigated is in a hidden tab, possibly subject to the following restrictions: 1) The window doing the navigating is not same-origin with the window being navigated. 2) The URL being navigated to is not same-origin with the window being navigated. 3) The window being navigated is its own .top (so a root window in the tab, not just a subframe). 4) The window being navigated is the opener of the window doing the navigating. 5) The window doing the navigating is not the opener of the window being navigated. 6) The window doing the navigating is not in the same tab as the window being navigated. Which of these restrictions do we actually want? Rereading comment 18, it sounds like we want #1 for sure and do not want #2? Do we care about #3? What about #6? That is, do we care about good.com loading an evil.com subframe by accident, which then waits until good.com is in a background tab and navigates its .top? For that matter, do we care about hidden tabs vs "hey, the user looked away from the phone for a few minutes; let's navigate the _foreground_ tab now"? Oh, and I think #5 is not too bad to do (with some false positives if pages null out the opener), but #4 would take some work (keeping track of "real" openers when we don't right now, since pages can null out the opener).
Hello, I've been working on a solution to prevent the window to change its location when the tab hasn't got focus. With the power of "copy-paste" from different sources, I came out with this: http://pastebin.com/LCNJWXcv You can also test it here: http://daniel-tomescu.com/hasfocus.html It seems to work as I expected (I find this strange, it happens rarely) on firefox mobile. Maybe it will be a starting point for you to build a client-side solution for this problem. Cheers!
>I've been working on a solution to prevent the window to change its location when the tab hasn't got focus. You don't want this - it basically breaks the web. Similarly, warning when a hidden tab changes location is trivial enough, but gives too many false positives. The discussion is which circumstances involving cross site scripting warrant a warning, and that's more tricky. Popping up too many warnings is terrible for security - users learn to click them away without reading very rapidly.
I'm going to unhide this bug... this issue has been much discussed (in the old bugs, for instance) and spoofing is a well-known technique in general. Although we appreciate the demonstration in this bug it does not qualify for a bug bounty since it's a known issue. Despite the claims in this bug about the importance of the title I'll note that the DESKTOP version of Firefox got rid of the title on Windows a long time ago (even having the space) and Australis is getting rid of it everywhere else I think (maybe not on Mac). I agree that a lot of users will be fooled regardless, but for those users who _do_ check (and there are lots of pages and articles reminding people to check) spoofing the URL is much much harder (especially if it's SSL) and less likely.
Assignee: nobody → mark.finkle
Flags: sec-bounty? → sec-bounty-
A final point on the title/URL side discussion: showing the URL becomes actively misleading when it's http://www.facebook.com.mysite.com/spoof.html On my large-screened HTC One in portrait mode, that shows as http://www.facebook.co… which — if anything — increases the user's confidence. Just about any URL is too big for a phone screen with common truncation techniques. For every counter-point (text narrowing, tablets in landscape mode…) one can rebut with "most users are on portrait phones" and "here's a longer domain name that still displays the issue". You'd need to redefine "check the URL" as something other than "look at the address bar".
Indeed, unless the address bar is positioned with the rightmost bit of the hostname right-aligned in it...
Is www.facebook.com an eTLD?
(In reply to On vacation Aug 5-18. Please do not request review. from comment #40) > Is www.facebook.com an eTLD? Oh, typo. http://everybodyknowshowiliketospoof.wwwfacebook.com/ Or whatever "suffix looks valid" URL you wish to pick for this thought experiment!
Ah, fair. That said, you could just as easily use "http://wwwfacebook.com", right? Doesn't matter what the screen size is... The only sane way to "check the url" in that case is to not look at the url at all, since you might well miss the lacking '.'.
Actually, the hostname+domain coloring/bolding we use on desktop (and even mobile?) would make those really obvious, so these examples don't prove anything.
This got some news today because someone mistook an old blog post for news, but anyway: http://www.azarask.in/blog/post/a-new-type-of-phishing-attack/ Nice POC from a former collegue...in 2010 :-P
In bug 1111729 we changed the default to always show the URL in the toolbar. However, the point about long sub-domains still applies here. Should we considering only showing the base domain? We already have logic in place to only highlight that part of the URL, so we could instead only show that in the toolbar until you click on it. This conversation has come up recently - is there another bug filed about this issue?
Bug 605206 was about the original issue, we went back and forth a bit here whether this is a dupe or not. I filed Bug 1236431 about the remarks I made on #mobile regarding origin display.
Both of the bugs GCP mentions are fixed. What's left for this bug?
Assignee: mark.finkle → nobody
We now show the page origin (public suffix + 1) by default, and the full URL when you click on it. The title is not shown by default. So I think this is fixed.
Status: NEW → RESOLVED
Closed: 5 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.