Target=”_blank” is an underestimated vulnerability
medium.com
medium.com
- 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.
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.
If the attacker can run the javascript you mentioned, they've already run.
- Disable JavaScript.
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.
I don't even enable JavaScript for google.com, not since they integrated the pile of crap that is/was Google+ which added 10% usage load on my CPUs.
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.
but my god, how the web got better!
practically no ads. no frills. some sites don't work, but then I just move to one that does or allow js there.
That's not fair. They state it's a problem that is inherent to browsers, not that they don't care about the issue.
Also be mindful of Google's warning regarding the author's workaround:
> in particular, clobbering the window.opener property limits one of the vectors, but still makes it easy to exploit the remaining ones.
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: malicious sites linking back to a parent that opened the, could browsers not also disable cross-origin .opener?
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.
Agreed CSP would be a good place to fix.
Why not? What's stopping browser from disabling window.opener unless CSP specifically allows it?
(totally appreciate there may be something I'm missing here, and thanks for responding)
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.
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.
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.
> Blocked a frame with origin "https://www.google.com" from accessing a frame with origin "https://news.ycombinator.com". Protocols, domains, and ports must match.
When executing
window.opener.location = 'javascript:alert(1);'But then I read this - https://www.chromium.org/developers/design-documents/site-is...
"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."
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.
I wonder if the reasons for implementing this are related or just good riddance :)
It would make scam pages much more expensive while still allowing most legitimate use. And it would be consistent with existing security policies.
https://developer.mozilla.org/en-US/docs/Web/API/Window/open...