There’s a little-known security risk built into the design of HTML. It concerns links that open in a new tab or window. You make it happen by specifying target="blank"
in an anchor (a) element. For example:
<a href="something.example.com" target="_blank">
The trouble is that when you do it, you put the page containing that link at risk. For some bizarre reason, the designers of HTML decided that the destination page should gain access to the window.opener
property of the source page. This gives the target page — the one run by someone else considerable control over your page. For instance, it can redirect your page to another URL.
I don’t know why this is the defined behavior. Probably someone thought it was a good idea back in the carefree days of HTML 1 or 2, and committees since then have felt it necessary to keep backward compatibility of security holes. I can imagine situations where the feature could be useful, but none where it’s necessary. Microsoft Edge doesn’t support window.opener
, so it doesn’t carry the risk described here.
For years I’ve been using this type of link, more or less aware of the risk. I use it only for pages I trust. But this has a couple of problems. First, what if the target page is hacked? The attacker might put JavaScript into it to look for a source page and mess with it. Second, domains can be abandoned or sold. Someone might pick up the domain cheaply and use it for malicious purposes.
Against this, there’s a lack of reported exploits. How often does anyone use this trick? But weaknesses that lie dormant for years can suddenly become the target of malware campaigns. Ransomware was possible for years before it became big news.
A safer way
There’s a simple way to remove this risk. Adding the rel="noopener"
attribute to the anchor. This denies the target page access. window.opener
. If you’re using a hosting system that doesn’t leave your HTML strictly alone, you should make sure the attribute is really there when you view the page on the Web. In testing on this site, I found that WordPress adds noreferrer
to the rel
attribute, which has a broader effect. The target page doesn’t know where the link came from and certainly can’t get access to its internals. The reason for using both is that some browsers don’t support noopener
.
A bigger problem is that many authors may not have access to the rel
attribute. LibreOffice lets you set the target
of a link, but not the rel
. Some hosts, though, will automatically add noopener
for you.
Page owners like target="_blank"
. It lets them link to an outside page without making their own page disappear. But is it worth the risk? If you’re writing for a customer, it’s ultimately their call. But my new resolution is not to put target=_blank
into any pages of my own unless I can set noopener
. If I don’t know my customer’s preference and can’t set both of those, I’ll omit the attributes.
SEO considerations
There’s no reason to think that blocking the opener adversely affects your SEO. There’s hardly ever a legitimate use for accessing a referring page’s DOM, so it would make no sense for search engines to penalize protecting it. It’s different from the rel=nofollow
attribute, which tells search engines to ignore the link. Using that can help or hurt your SEO, depending on many considerations.
However, noreferrer
keeps the site you link to from seeing that you’re driving traffic to them. They might link back to you if they see that you’re sending readers their way. If they don’t know about your links, they won’t. It’s not clear if it improves security.
In a lot of cases, the best thing is to forget about target="_blank"
and let the user have control. They can always control-click (command-click on a Mac) if they want the link to open in a new page. They may be happier not to have their browser cluttered with windows.
The decision is up to you and your clients. Just keep the risk in mind and avoid using target="_blank"
without additional protection if you can.