Note that Google quietly turned into my profile page. Now, imagine that it instead turned into maliciousgoogle.com, which looks just like Google, and you can see the attack vector.
First we had pop-ups that opened on top of the current window
Then we had pop-unders that opened behind the current window
Now we have... what? pop-switches? that open your link target in a new window and change the source page to the "pop(-up)" behind your back.
Impressive idea, I opened both windows on purpose so they couldn't be blocked or else I wouldn't get to my content and one was transmogrified to an ad page behind my back.
Seriously, seeing all these interesting behaviours just makes me advocate even more strongly browsing the "open Web" with JS off by default. The power of JavaScript is not to be underestimated, and while it makes for some very good things that would be otherwise impossible, I think users should be more aware of and understand the risks that allowing any page to run JS can imply.
I only allow JS for a very small number of sites which I thoroughly trust and require it, and haven't missed it one bit; the fact that it automatically rids a lot of other surprising and annoying things pages can do, besides phishing or exploiting you, is a nice bonus.
(Assuming I'm understanding the exploit correctly, obviuosly:)
Limiting JS to a few sites won't protect you fully from this attack, though it will obviously limit your exposure.
If one of your trusted sites, A, has been compromised by, say, an XSS attack, with the ability to inject JS then this attack can be leveraged to also compromise your access credentials to site B by redirecting your login attempt on site B to a malicious imitation of site B's login page. (Of course this assumes that you already have B open in a tab somewhere and that you opened site A through a _blank link on site B. Mostly I would think that would be a plausible scenario for sites mostly based on user-generated content such as forums, social media, and such.)
AFAICT always explicitly force-reloading any login page should make you a lot safer, but remembering to always do that is perhaps not realistic.
The "benefit" is that it causes a "trusted" tab to change, not a new one that a user might expect to be tainted. If I open a link from HN (for example), read it, and close the tab, I'd expect to be back at HN. If the link changed my `window.opener` url to a fake-HN, I could do some action that asks for a password or some similar data. It's more likely to succeed since the user already trusts the existing window/tab/site.
The attack I linked to originates from the malicious site and links to the trusted site (the reverse of the attack in this post). There is nothing a site can do to prevent this since there is no way for a linked to site to prevent the linking site from getting a window reference to it. So, imagine a scenario like this:
* trusted site implements the guidance here and links to malicious site.
* The malicious site, detecting that they can't get a reference to "window.opener" immediately opens a new tab back to the trusted site (maybe to the login page if the site has any logout CSRF issues).
* The user is slightly confused, but they were just on the trusted site, so it doesn't feel too strange.
* If the user is super savvy, the look up at the URL bar and are assured that they actually are back in the trusted site (possibly staring at a login prompt).
* the attacker has a reference to the window they opened back to the trusted site. They set a timer for a couple seconds (like the attack I referenced above). After a few seconds they change the trusted site to load a malicious site and/or malicious data URL.
* user "logs in to the trusted site" and gives up their creds.
Re: http://lcamtuf.coredump.cx/switch/, couldn't browsers simply do a better job of showing the address when window.location.href is 'data:text/html;-peak.us/banking_interface/' or any other data URL?
Re: malicious sites linking back to a parent that opened the, could browsers not also disable cross-origin .opener?
Sure...but that is another thing that needs to be added to all browsers; it begins to feel like a game of whack-a-mole. In the end, browsers rely on an admittedly fragile premise...the only thing that guarantees your current location is a persistent awareness of what domain you are on. Most of the time that works for savvy users (normal users have no fighting chance/nor should they be expected to have to do this). But, these various edge cases break the reasonable expectation that the domain I'm on will stay the domain I'm on until I explicitly do something.
In my opinion, the better place for a more holistic fix to this is within Conntent Security Policy. That could, theoretically, address all attacks that somehow obtain a window ref. The CSP policy could say "window-ref: 'none'". That would be a declarative policy that the browser could enforce in any situation where a window ref might be available.
Another benefit of implementing it in CSP is that you could retroactively fix existing sites without having to go back and fix up potentially thousands of links that didn't set the attribute mentioned in this article.
Of course it's whack a mole. Moat things in infosec are, that doesn't mean browsers shouldn't ship with secure defaults or present trustworthy info in the address bar.
This game off whack-a-mole feels different. Unlike the typical "memory corruption of the week", this kind of stuff isn't fixed by a simple browser update and inherited "for free" by all sites. And, this kind of fix doesn't enable a browser to ship with a secure default. Instead, it adds a new thing you have to opt into and retroactively add to all existing links on your site. That is a fair bit of work, and adding more and more of those kinds of features for nominal gain is a tough sell. That is a much more painful game of whack-a-mole and isn't an approach that scales well. The CSP solution at least has a potentially simpler scaling solution to the problem.
Unless we are talking about something terribly dire (arbitrary code execution) browser vendors are super unlikely to change behavior that has existed, and potentially relied upon, for many years. The bar for changing existing behavior is extremely high and this kind of attack won't come anywhere near meeting it. So, the only realistic solution is something that a site opts into (or out of depending on your perspective). CSP would at least let the site that is a potential victim protect itself. And, if there was a good reason to let a partner site have window ref (I could imagine something related to payment providers and modal pop up payment flows), they could opt in to that. It would look something like.
window-ref 'self' PayPal.com
Something like that would let the site reference their own windows as well as grant access to a "trusted partner" like PayPal.
Browser vendors do 'phase out' old behavior and phase in new ones. I understand "don't break the web", but as someone else famously replied, "the web is a self healing mechanism". Look at what browsers have done re: forms submitted over HTTP.
A maintained site that relies on window.opener should, after a 24 month period of angry console warnings saying a change needs to be made, actually make that change.
> The newly opened tab can then change the window.opener.location to some phishing page.
This is true, and is a vulnerability I have been looking at for a while now, though I've not actually seen it exploited yet in the real world. For anyone interested, there are some pretty interesting exploits involving pages where an auth token is in the querystring and thus sent in the referer field by the browser. Also, consider what happens when you use an alert() in javascript to yank context back to the now attacker controlled tab...
> Or execute some JavaScript on the opener-page on your behalf…
Not true, this implies the "attacker" can run javascript in the context of the original page. They can only run javascript after redirecting the original page to one they control, so it's not like they can run code on the facebook.com domain, which would be a _huge_ exploit.
What happens if they change `window.opener.location` to a javascript: URI? I'm assuming (well, hoping) it fails to work, but it would be nice to have that confirmed.
If you do that cross-origin, the script will not be executed, both per spec and in browsers. That would be a pretty wide-gaping security hole if it worked...
Yep. Open requested link in a new tab, change the previous tab to some autoplay video or fake chat interface. It's not phishing exactly, but it is certainly devious.
To be fair, not all of those chat interfaces were fake. Some are just scripts that connect to real people quickly once you interact favorably. Then they try to sell you on $50 of cam show credits.
At Flexport, a security audit revealed we were vulnerable to this. So we made a linter to detect it. If you use React like we do, maybe our linter will be useful to you too: https://github.com/yannickcr/eslint-plugin-react/pull/582
So quite apart from being a crime against usability, now it turns out target="_blank" is a great big security hole, too. I fear this isn't going to be solved 'the flash way' (i.e. by ditching it altogether) but just by making window.opener.location read-only (but maybe only for different domains). One can still dream, though.
I was really surprised to find out that this works in chrome, since the "site-per-process" policy was one of the major ideas that google implemented and advocated - and different processes shouldn't have access to the same memory space.
"Most renderer-initiated navigations (including link clicks, form submissions, and scripted navigations) are kept within the current process even if they cross a site boundary. This is because other windows in the same process may attempt to use postMessage or similar calls to interact with them."
This article is incorrect about this being a vector for executing JavaScript (the same origin policy prevents that), but the phishing potential from redirecting the opener page to a fake URL is definitely cause for concern.
In what world would a cross domain version of this be a good idea? Maybe there's a legit use case within the same domain (think 90's HTML frames), but cross domain?!
Actually thinking about it more, it's same world that connects to remote servers over plaintext telnet. Oh and you don't need to verify your identity either, user's will just say who they are and we'll trust them.
Which points to the fact that target= is a very bad idea in the first place. As a web developer, it's not my concern or business what window/tab combination my reader views a link in (mechanism vs. policy and all). If I decided to hijack the browser's and user's preferred target policy, then yeah, I'm opening myself up to some exposure to what that link does.
For you Firefox users, try the add-on RequestPolicy (https://requestpolicycontinued.github.io/) and before a site opens or redirects to another domain, you'll be prompted (you can make policies around your decision for future instances.)
It seems like there's an easy fix... infer 'rel=noopener' by default on every https site that opens an http site. Or just don't allow http pages to redirect https pages.
It would make scam pages much more expensive while still allowing most legitimate use. And it would be consistent with existing security policies.
This is not a very informative article. It doesn't explain how the attack works (e.g. what is the window.opener object? how can an attacking page modify it? what's the trick and why is it important?).
Same here. I build a demo for that: https://gist.github.com/mems/df881c9495b6744b650c
It's display a fake Facebook login page (just HTML and CSS). You can try with your relatives. How many people fall into the trap?
- Open a website, let's say google.com
- Open a console and type in `window.open("http://xkcd.com")`
- Disable your popup blocker and do it again.
- Open a console in the new xkcd window and type in `window.opener.location = "https://news.ycombinator.com/user?id=Cpoll"`
Note that Google quietly turned into my profile page. Now, imagine that it instead turned into maliciousgoogle.com, which looks just like Google, and you can see the attack vector.