For those who haven’t yet noticed, WordPress now adds
rel="noopener" attributes for any external links added via the link Quicktag in the Visual/RTE. So if you enable the option, “Open link in a new tab”, WordPress automatically will add the rel noopener attribute to the link. This is to protect against CORS and other exploits that take advantage of blank-target links. It’s a smart move that may escape many in the WordPress community. So in an effort to help foster understanding, this post explains how it works and why it’s beneficial, and then explains some ways to workaround, enhance, disable, etc.
Try it for yourself
The best way to understand how it works, is to try it yourself. There are two ways to reach the Insert Link dialog box: via the RTE/Visual Editor, or via the Plain-Text Editor. Here are steps for the plain-text editor (you can follow similar steps to get there via the RTE/Visual Editor):
- Visit Edit Post screen for any post
- Use the Visual/RTE (Tiny MCE) editor
- From the editor toolbar, click the link quicktag
https://example.com/for the URL
Exampleor whatever for the Link text
- Check the box, “Open link in a new tab”
- Click “Add Link”
You can see an example of the dialog prompt in the screenshot above. After adding the link to your post content, you will notice that WordPress now adds both
rel="noopener" to the link markup. Here is an example of the generated HTML:
<a href="https://example.com/" target="_blank" rel="noopener">Example</a>
And for those with Code Inspecting Powers (CIP), you can examine the actual link markup via your browser: Example. Notice the
noopener included in the anchor markup? That tells supportive browsers to disown the opened page, which in turn protects against any possible exploits. The keyword here is “supportive browsers” — not all browsers yet support noopener.
rel="noopener"on any blank-target links that are added manually (i.e., any links added without using the Insert Link tool). This includes ALL web pages, not just those powered by WordPress.
Why are they doing this?
Used in WordPress core, the Tiny MCE (Visual/RTE) script adds the rel-noopener attribute to help protect against a potential CORS vulnerability involving blank target attributes on anchor elements. In plain English, adding
target="_blank" to your links is considered unsafe, so WordPress now adds
rel="noopener" to inserted blank-target links to protect against CORS and other exploits. Such exploits also are referred to as “link jacking”, “tab nabbing”, and similar names. Among myselves, I simply refer to it as the “blank-target issue”. So how does it work? Glad you asked..
The blank target issue
I first heard about this security issue from Mathias Bynens and Ben Halpern. Basically the way it works is that browsers give the blank-target destination page full control over the window object of the source page. And that in turn opens the door to all sorts of hacks and exploits. Fortunately, there are ways to protect against such attacks, ad we’ll cover a bit later in the article. For now, an important thing to understand about this potential vulnerability, is this:
Blank target is an issue only for untrusted links.
Think of it this way. In order for the blank-target hack to work, the attacker must have control of the target page. For example, if I have a blank-target link pointing at Facebook, like this:
<a href="https://www.facebook.com/" target="_blank">Facebook</a>
For this blank-target link to be exploited, the attacker must have control of the Facebook homepage, in order to execute whatever malicious script. For another example, say we have a blank-target link pointing at a cool blog post located on some obscure, random website:
<a href="https://some-obscure-random-site.com/cool-thing/" target="_blank">Something cool</a>
As with the pervious example, in order for this blank-target link to be exploited, the attacker must have control of the page located at
https://some-obscure-random-site.com/cool-thing/. If the attacker does not have control of that web page, the blank-target link is totally safe.
Understanding the risk
The main thing to understand is that, in order for blank-target links to be unsafe, the attacker needs control of the target page in order to execute their script. Otherwise there is no threat and the blank-target link is completely safe and secure. So it’s all about trust: do you 100% trust the pages that you’re linking to? If so, you have absolutely nothing to worry about.
YES that’s really what the blank-target hack is all about. Whether or not the pages that you link to via target-blank will ever be compromised by link-jacking bandits. Like if you link to big corporate sites, your blank-target links probably are pretty safe. But if you link to smaller sites that may be more likely to fall under the influence of bad actors, then there is a greater risk that some lowlife would actually attempt some link-jacking buffoonery.
Protect and secure
If you recall from the previous discussion:
Blank target is an issue only for untrusted links.
The problem of course is that, web pages that are trusted today may fall prey to bad actors in the future. So even though there are specific cases and scenarios where external blank-target links always will be trusted, it is recommended to treat all blank-target links as unsafe.
So then how to protect and secure your external links? Here are some recommendations, organized by overall ease and effectiveness:
- Best protection (recommended)
- If possible, simply avoid using
target="_blank"on any links anywhere, ever. This is simple to implement and literally eliminates the vulnerability 100% done. And for any external links that absolutely must be opened in a new tab, use
- Best protection (alternate strategy)
- Instead of
rel="external"for external links. Using the rel-external attribute is better semantics than blank target. And if you need the external link to open in a new tab or window, you can add the following slice of jQuery:
- Average protection
- Add the
rel="noopener"attribute to any blank-target links. Like WordPress does with blank-target links inserted via the Insert Link tool. Using the rel-noopener attribute protects blank-target links in the latest versions of all major browsers. Unfortunately, support for rel-noopener only goes back so far. Older versions of Chrome, Firefox, Opera, Safari, IE (et al) do NOT support rel nopener, so extra support is required to secure blank-target links for older browser versions.
- Older browsers
- To cover older versions of browsers, include rel
noreferreron blank-target links, like so:
<a href="https://example.com/" target="_blank" rel="noopener noreferrer">Example</a>
var otherWindow = window.open(); otherWindow.opener = null; otherWindow.location = url;
<iframe>that opens the new tab, and then immediately remove the iframe. More about this here.