Target=_blank implies rel=noopener | Stefan Judis Web Development
If you want to be a good web citizen, you might know about the target="_blank"
security issue.
In the old days, when you linked to a site and wanted to open a new tab with target="_blank"
, the target site could access your site via window
. This means in short:
If window A opens window B, B.opener
returns A.
Suppose you haven’t heard of this behavior; it’s pretty wild because it implies that target pages could check if window
is accessible and, if so, change the location of your site with trivial JavaScript. This process is also known as “reverse tab nabbing”.
if (window.opener) {
window.opener.location = 'https://you-re-hacked.com';
}
Ooooff… And while it’s unlikely, someone could now use XSS to inject target="_blank"
links into your site and, when someone clicks on them, change the URL of the original site (which is now in the background) to a malicious copy to fish credentials.
To prevent this, you could use rel="noopener"
.
<a href="some-site.com" target="_blank" rel="noopener">
Some site
a>
But guess what? Because this behavior seemed so off, browsers changed it. In 2024, whenever you use target="_blank"
rel="noopener"
is implicit. Yay!
<a href="some-site.com" target="_blank" rel="noopener">
some site
a>
<a href="some-site.com" target="_blank">
some site
a>
But is this new stuff? Nope.
Yet, the internet is full of rel="noopener"
advice, and it continues to live on.
But guess what? There’s yet another approach to avoid cross-origin security attacks.
Ignoring that most browsers implicitly set rel="noopener"
, it’s still cumbersome to slap the rel
attribute on every link that opens a new tab or window to a site you don’t control.
Shouldn’t there be a single place to define that you don’t want to share the window
context with other origins?
And there is — the Cross-Origin-Opener-Policy (COOP)).
The HTTP Cross-Origin-Opener-Policy (COOP) response header allows you to ensure a top-level document does not share a browsing context group with cross-origin documents.
Set the HTTP header and forget about the window
problem entirely.
COOP is pretty well supported these days (the MDN compat data seems incorrect at the time of writing).
If you don’t have access to your server infra, unfortunately, you can’t set Cross-Origin-Opener-Policy via a meta
element.
Where does this investigation lead me?
According to caniuse.com, implicit rel=”noopener” has a global support of 94% at the time of writing, while the Cross-Origin-Opener Policy has a global support of 91%.
For me this browser support is good enough and I’ll stop thinking about the window
problem. To be very sure I might add the Cross-Origin-Opener-Policy
header to my sites because it’s always good to be more secure.
Don’t take my word for it, though; if ~95% overall browser support isn’t enough for you, totally fine. There’s nothing wrong with adding rel="noopener"
to some links. Each their own. 😉