This site uses cookies for analytics. By continuing to browse this site, you agree to this use.
A JS Foundation Project

Require external links to disown opener

Require external links to disown opener (disown-opener)

disown-opener checks if the rel attribute is specified with both the noopener and noreferrer values (or only noopener if all the targeted browsers support it) on a and area elements that have target="_blank" and link to other origins.

Why is this important?

Links that have target="_blank", such as <a href="https://example.com" target="_blank"> constitute:

  • a security problem

    When using target="_blank", the page that was linked to gains access to the original page’s window.opener. This allows it to redirect the original page to whatever it wants, a technique frequently used for malicious attacks on the user. For example, the user could be redirected to a phishing page designed to look like the expected page and then asking for login credentials (see also: tab nabbing).

    By adding rel="noopener" (and noreferrer for older browsers) the window.opener reference won’t be set, removing the ability for the page that was linked to from redirecting the original one.

  • a performance problem

    Most modern browsers are multi-process. However, in most browsers, due to the synchronous cross-window access the DOM allows via window.opener, pages launched via target="_blank" end up in the same process as the origin page, and that can lead to the pages experiencing jank.

    In Chromium based browsers, using rel="noopener" (or rel="noreferrer" for older versions), and thus, preventing the window.opener reference from being set, allows new pages to be opened in their own process.

    Edge is not affected by this.

Notes:

  • Not all browsers support rel="noopener", so to ensure that things work as expected in as many browsers as possible, by default, the hint requires both the noopener and noreferrer values to be specified. However, if all the targeted browsers support noopener, only noopener will be required.

  • The reason why the hint does not check the same origin links by default is because:

    • Security isn’t really a problem here.
    • When it comes to performance, making same origin links open in their own process works against optimizations that some browsers do to keep multiple same origin tabs within the same process (e.g. share the same event loop).

    Check Can the hint be configured? section to see how the hint can be made to also check same origin links.

  • noopener and noreferrer only work for a and area elements.

  • In the future there may be a CSP valueless property that will prevent the window.opener reference from being set.

What does the hint check?

By default, the hint checks if the rel attribute was specified with both the noopener and noreferrer values on a and area elements that have target="_blank" and link to other origins.

If the targeted browsers are specified, based on their support, the hint might only require the noopener value.

Let’s presume the original page is https://example1.com.

Examples that trigger the hint

<a href="http://example1.com/example.html" target="_blank">example</a>
<a href="https://en.example1.com" target="_blank">example</a>
<a href="//example2.com" target="_blank">example</a>
<a href="https://example2.com" target="_blank">example</a>
<img src="example.png" width="10" height="10" usemap="#example">
<map name="example">
<area shape="rect" coords="0,0,5,5" href="http://example3.com/example.html" target="_blank">
</map>

Examples that pass the hint

<a href="/" target="_blank">example</a>
<a href="example.html" target="_blank">example</a>
<a href="https://example1.com/example.html" target="_blank">example</a>
<a href="http://example1.com/example.html" target="_blank" rel="noopener noreferrer">example</a>
<a href="https://en.example1.com/example.html" target="_blank" rel="noopener noreferrer">example</a>
<a href="//example2.com" target="_blank" rel="noopener noreferrer">example</a>
<a href="https://example2.com" target="_blank" rel="noopener noreferrer">example</a>
<img src="example.png" width="10" height="10" usemap="#example">
<map name="example">
<area shape="rect" coords="0,0,5,5" href="example.html" target="_blank">
</map>
<img src="example.png" width="10" height="10" usemap="#example">
<map name="example">
<area shape="rect" coords="0,0,5,5" href="http://example3.com/example.html" target="_blank" rel="noopener noreferrer">
</map>

Can the hint be configured?

includeSameOriginURLs can be used to specify that same origin URLs should also include rel="noopener noreferrer".

In the .hintrc file:

{
"connector": {...},
"formatters": [...],
"hints": {
"disown-opener": ["error", {
"includeSameOriginURLs": true
}],
...
},
...
}

Also, note that this hint takes into consideration the targeted browsers, and if all of them support the noopener value, the hint won’t require the noreferrer value.

How to use this hint?

To use it you will have to install it via npm:

npm install @hint/hint-disown-opener

Note: You can make npm install it as a devDependency using the --save-dev parameter, or to install it globally, you can use the -g parameter. For other options see npm's documentation.

And then activate it via the .hintrc configuration file:

{
"connector": {...},
"formatters": [...],
"hints": {
"disown-opener": "error",
...
},
"parsers": [...],
...
}

Further Reading