Security and Performance Benefit from the rel=”noopener”

Opening links in a new window is a generic method to navigate the users to another domain. We can achieve this using target=”_blank”. I’m sure everybody used the target with _blank value in some of his projects, but I’m not sure everybody knows the drawbacks of it.

Fortunately knowing the disadvantages of opening a link is more widespread thanks to Mathias Bynens (who come up with this problem first) and other authors. As usual, this is a kind of topic which worth to mention again mostly for our user’s safety and who didn’t know about it.

About the Security

When you open a new document through a link with target=”_blank” the opened document can access the opener document’s object. If you are open the same origin you have full access – to the document object too – on cross-origin this is disabled (window.opener.document), but you can still access the location object.

It means that if you embed a link into your site or article which point to another page – and opened in a new window – the target page can modify the original page in some way through JavaScript using window.opener object. It’s easy to imagine the wicked problems this can cause. A basic answer can be the modification of the links or cookie read (this is just in the same domain, it is limited but can happen). A more sophisticated solution would be some redirection where a malicious script asks for personal credentials after a redirect.

To see this in work, please navigate to this linkjust for the test, it won’t harm you I swear.

So what happens here? After you click on the link (in the opened document), the browser opens the page which runs a script that using the window.opener object to modify the original page (which you come from). Plain dull but can be harmful.

The last question is: how we can disable this behavior? Use rel=”noopener” on every link which is using target=”_blank” and navigate to another document.

<a href="https://adamlaki.com" rel="noopener"></a>

In older browsers, you can use rel=”noreferrer”, but this also removes the referral header.

<a href="https://adamlaki.com" rel="noopener noreferrer"></a>

This also applies if you open the window through JavaScript window.open(); function because you also open a window. In this case, you have to clear the opener object:

var newWindow = window.open();
newWindow.opener = null;

About the Performance

In some extreme cases, the opener object can lead to performance problems which are connected to the browsers main thread handling. Jake Archibald came up with the exciting find which is nice to know.

Summary

It is a small and ridiculous problem which can cause some headache. As a developer, we need to protect the users against this kind of vulnerabilities. Now, this parameter is default in WordPress if you use blank target, but this is not a big job to make a filter in other systems too so why not to do it?

5 thoughts on “Security and Performance Benefit from the rel=”noopener”

  1. Thanks for sharing this. I’m a bit old school so I didn’t know what that attribute was on all of my WordPress’ blank links, but that’s an interesting insight.

    I like that there are ways around this, but I feel like the default behaviour should be the opposite, with a rel=”opener” attribute added should you want that object information to be passed.

    It reminds me of iframe’s sandboxing, it should be there by default, with additional permissions allotted where necessary. https://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/

    1. Hi Michael!

      I’m glad it was useful! To be honest, I didn’t know too that WordPress handles it automatically until I tried to insert a direct blank with the example! 🙂

      From the developer view, I can’t image why it works like this. I think your point is valid, using reversely could be better for us.

      I didn’t hear about the iFrame’s sandboxing so thanks for the info and the article!

      Thanks,
      Adam

  2. This is WRONG. Cross origin restriction blocks this. This is the error that you get when you try to do this across different origins:

    Uncaught DOMException: Blocked a frame with origin “http://website.com” from accessing a cross-origin frame.

    1. Hi Andrei!

      Sorry, I made a mistake, corrected. Using cross-origin, you can’t access the document object, but you can still access the location object.

      Thanks for the comment and the report,
      Adam

Leave a Reply

Your email address will not be published. Required fields are marked *