Why am I seeing rel=”noopener noreferrer” in my WordPress links?

As of WordPress 4.7.4, when you include a link in a post that opens in a new tab, WordPress will automatically modify the link to include the following rel attribute:

<a href="https://www.google.com" target="_blank" rel="noopener noreferrer">Google</a>

With the rel attribute set this way, the site you browse to will not receive the Referrer in the header of your request. That means any tracking they are doing, like through Google Analytics, will not display your website as being a referring site. You may depend on external sites seeing your domain in their analytics to prove value or popularity or something, so you may not want this new functionality in 4.7.4.

Discussion

First, let’s look at what these two rel types do. MDN has the information we need:

  • noopener
    “Instructs the browser to open the link without granting the new browsing context access to the document that opened it — by not setting the Window.opener property on the opened window (it returns null).”
  • noreferrer
    “Prevents the browser, when navigating to another page, to send this page address, or any other value, as referrer via the Referer: HTTP header.”

In a forum thread about this reported issue at WordPress.org, a user wrote:

This has probably been done to avoid what is known as Reverse Tabnabbing. Reverse Tabnabbing occurs [when] the attacker uses window.opener.location.assign() to replace the background tab with a malicious document.

What is “reverse tabnabbing”? Ben Halpern wrote an article about this vulnerability and goes into some good detail, so feel free to read that.

If noopener fixes reverse tabnabbing, why is noreferrer also included in the fix for this problem in WordPress?

According to Ben Halpern’s article, it’s because Firefox doesn’t support the noopener attribute, so since noreferrer also fixes this vulnerability, that one can be included too as a fallback.

Let’s also note that this is actually an issue with TinyMCE, the WYSIWYG editor that WordPress uses to write posts and pages. In version 4.7.4, WordPress included an update from TinyMCE that changes the handling of target=_blank links in the editor, so that’s actually what changed behind the scenes in WordPress.

Another question I’ve seen is why these attributes are being added to both external and internal links. If the link is to your own site, shouldn’t it be OK? While the answer may be yes, it appears these attribute modifications are being made regardless where the link is going. I asked why they did it this way on the GitHub issue where they discussed the vulnerability, so I’ll update this post if someone responds.

We’ve had some good discussion in the comments below about this vulnerability, so I would encourage you to give the comments a read! One topic that came up is if including rel="noopener noreferrer" would affect affiliate links, like through Amazon’s affiliate program. It will depend on how your affiliate program works, but the majority will include a query string parameter with your affiliate ID. Amazon does it this way – they add the query string parameter of  tag=[YOUR_AFFILIATE_ID]  to Amazon links. The user Tasha correctly pointed out in the comments that the Referrer request header is unreliable, as it can be modified or removed entirely, so most affiliate services will use the query string. To sum up affiliate links: if you use Amazon’s affiliate program or another program that tracks affiliate click-throughs via a query string parameter, you can safely allow rel="noopener noreferrer" on your links.

Daniel St. Jules wrote a handy cross-browser plugin called blankshield to accommodate for the Reverse Tabnabbing vulnerability, but since we’re using WordPress, let’s find a WP solution.

The Solution

Keep in mind, if you choose to remove the noopener and noreferrer attributes on target=_blank links, you are vulnerable to reverse tabnabbing, so do this at your own risk.

Steve Stern wrote this solution in the forums at WordPress.org:

If, after reading the above, you want to disable the new setting, you can overide it with this in your functions.php or in a plugin. It is not recommended.

// Note that this intentionally disables a tinyMCE security feature.
// Use of this code is NOT recommended.
add_filter('tiny_mce_before_init','tinymce_allow_unsafe_link_target');
function tinymce_allow_unsafe_link_target( $mceInit ) {
    $mceInit['allow_unsafe_link_target'] = true;
    return $mceInit;
}

Note if you implement this solution, it will not change any posts or pages that already exist. This only changes the way TinyMCE works when you click to edit a post or page from then on.

If you do end up doing this, I would highly suggest still at least manually adding the noopener attribute to your target=_blank links. That will protect your site in many cases, although not all.

Your Turn!

Have you encountered this problem? What are your thoughts on this vulnerability and possible solution? Did you disable the noopener/noreferrer functionality on your WordPress site? Leave a comment below, and let’s discuss!