
Target=”_blank” is an underestimated vulnerability - SimplyUseless
https://medium.com/@jitbit/target-blank-the-most-underestimated-vulnerability-ever-96e328301f4c#.disn238f9
======
Cpoll
For anyone that wants to see this in action:

\- Open a website, let's say google.com

\- Open a console and type in
`window.open("[http://xkcd.com")`](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"`](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.

~~~
userbinator
For anyone who wants to see this defeated:

\- 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.

~~~
IgorPartola
The web now requires JS to function. I think it's time to take off the tin
foil hat and accept it.

~~~
smt88
Unfortunately, two things can be true at the same time: JavaScript increases
security risk, and JavaScript is necessary for a lot of the web.

------
throwawaybookst
_> PS. Interestingly, Google doesn’t seem to care._

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._

~~~
nailer
I'd be interested in knowing the others. So would I imagine most people
reading that page.

~~~
ptoomey3
I mentioned this on another related thread:
[https://news.ycombinator.com/item?id=11554080](https://news.ycombinator.com/item?id=11554080).
In short, the solution here only closes one of potentially many other similar
attacks:
[http://lcamtuf.coredump.cx/switch/](http://lcamtuf.coredump.cx/switch/)

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.

~~~
nailer
Re: [http://lcamtuf.coredump.cx/switch/](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?

~~~
ptoomey3
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.

~~~
nailer
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.

Agreed CSP would be a good place to fix.

~~~
ptoomey3
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.

~~~
nailer
> this kind of stuff isn't fixed by a simple browser update and inherited "for
> free" by all sites

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)

~~~
ptoomey3
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.

~~~
nailer
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.

------
nmjohn
> 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.

~~~
eridius
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.

~~~
nmjohn
At least in chrome, you get the warning:

> Blocked a frame with origin
> "[https://www.google.com"](https://www.google.com") from accessing a frame
> with origin "[https://news.ycombinator.com"](https://news.ycombinator.com").
> Protocols, domains, and ports must match.

When executing

    
    
        window.opener.location = 'javascript:alert(1);'

------
zerd
I guess this is the trick 99% of porn sites use to do "pop-unders" now.
Shouldn't the fix for this be in the browers?

~~~
briHass
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.

~~~
emidln
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.

~~~
rocky1138
Wait, how do you know that? :P "Market research" eh?

~~~
tamana
Please don't mock fellow HN users.

------
bluesmoon
Looks like an almost verbatim copy of [https://mathiasbynens.github.io/rel-
noopener/](https://mathiasbynens.github.io/rel-noopener/)

------
dmnd
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](https://github.com/yannickcr/eslint-plugin-react/pull/582)

------
oneeyedpigeon
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.

------
idoco
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.

But then I read this - [https://www.chromium.org/developers/design-
documents/site-is...](https://www.chromium.org/developers/design-
documents/site-isolation)

"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."

------
simonw
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.

------
joveian
Is there a canonical safe way to pop up a link in a new tab/window? This seems
like a major bug and hopefully browser vendors will fix it quickly.

~~~
mnarayan01
Add rel="noreferrer". As you can probably guess, that also removes the
referrer, but if you really want to be "safe", you need to do so anyway.

------
koolba
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.

------
bandrami
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.

------
dakull
Twitter's t.co links seem to mitigate this by issuing a 301 to the actual link
thus fixing the `window.opener.location` vulnerability.

I wonder if the reasons for implementing this are related or just good
riddance :)

~~~
ams6110
They are tracking links.

------
G3E9
For you Firefox users, try the add-on RequestPolicy
([https://requestpolicycontinued.github.io/](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.)

------
wmil
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.

~~~
cyphar
Then the scammer can use let's encrypt. The solution should be that
window.opener shouldn't work cross-domain.

------
gcr
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?).

~~~
WhoBeI
Read the mdn post I link below as well and it should become clear.

[https://developer.mozilla.org/en-
US/docs/Web/API/Window/open...](https://developer.mozilla.org/en-
US/docs/Web/API/Window/opener)

------
rpedela
How are rel=noreferrer and rel=noopener equivalent in Firefox?

~~~
gpvos
IIRC noreferrer, besides suppressing the Referrer: header, also does what
noopener does. There's a bugzilla entry to implement noopener in Firefox.

------
brador
What to use instead if I need the link to open in a new tab/window?

------
LunaSea
I reported this issue to Google, Facebook and GitHub. Google and Facebook were
not interested and GitHub was already working on a fix.

~~~
mmems
Same here. I build a demo for that:
[https://gist.github.com/mems/df881c9495b6744b650c](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?

