WordPress and the Blank Target Vulnerability
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
- Enter
https://example.com/
for the URL - Enter
Example
or 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 target="_blank"
and rel="noopener"
to the link markup. Here is an example of the generated HTML:
<a href="https://example.com/" target="_blank" rel="noopener noreferrer">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 vulnerability
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" rel="noopener noreferrer">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" rel="noopener noreferrer">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.
Otherwise, if there is even a remote possibility that, at some point in the future, the pages to which you link via target blank might possibly be taken over by a bad actor who then hosts some evil link-jacking JavaScript with the sole intent of fooling your visitors into revealing sensitive information when trying to log in, make a purchase, or via some other interactive UI trickery.
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, userel="external"
instead. - Best protection (alternate strategy)
- Instead of
target="_blank"
, userel="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: -
$('a[rel="external"]').attr('target', '_blank');
- FYI: Here are a couple of tutorials with more information about using JavaScript and jQuery to open external links in their own tabs.
- 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
noreferrer
on blank-target links, like so: -
<a href="https://example.com/" target="_blank" rel="noopener noreferrer">Example</a>
- Then back that up with this bit of JavaScript:
-
var otherWindow = window.open(); otherWindow.opener = null; otherWindow.location = url;
- Note: this JavaScript technique fails in older versions of Safari. For Safari support, inject a hidden
<iframe>
that opens the new tab, and then immediately remove the iframe. More about this here.
noreferrer
is no longer necessary for the blank target fix. This is true only if you ignore Internet Explorer, Edge, older versions of Firefox, and various other browsers. At the time of this writing, IE and Edge together have nearly 8% market share. So eventually it will be safe to remove noreferrer
, but not yet.Related
- The Friendliest Link Targets in the Neighborhood
- Open External Links as Blank Targets via Unobtrusive JavaScript
- Targeting External Links Intelligently
- jQuery Open Links in New Tab