tl;dr: When adding the target
attribute to an a
element which takes you to a property you do not own, you must add rel="noopener noreferrer"
.
Info
When you open a link using target
, for example in a new tab (target="_blank"
), the browser may, not done universally but Firefox & Chrome both do it, set the window.opener
of the new tab to be the original window. This means that the new tab can access some of the info from the original window/tab.
If it is on the same domain then that is a lot, including cookies and content. If it is on a different domain then same origin policy will protect that information, though some things are still available.
Attack Vectors
These attack vectors are very targeted and don’t represent a major risk IMHO but at the same time, the cost of doing this is less than the risk so it is a recommendation from me.
Same Domain
It is not uncommon for a single domain to have pieces built by multiple teams, especially as web components get better adoption so a vulnerability in any team contributing to the content now has the potential to impact all teams.
For example: https://badsite.com/login.html is built by teamA and has a simple login to the backend. https://badsite.com/products.html is built by teamB and is a public site listing products. If the login had a link to products which opened in a new tab then all JS in products can manipulate the login page, for example by silently injecting code which sends the login details to the attacker. This example is also a good reason to embrace sub-resource integrity, especially if you are using a CDN for JS, CSS etc…
It is also possible to use document.domain to get increased access to super domains; though things like cookies are still not accessible since the change will have been detected.
Different Domain
In this scenario, the data is really locked down though there are two possible attack vectors here.
Location Changes
The location of the parent window/tab can be changed. This could allow an attacker to redirect the original window/tab to a page which has a vulnerability in it or in a targeted attack, it could open to a page that looks the same.
For example: You open a link from your bank’s website to a 3rd party. That 3rd party has a piece of JS (either intentional or unintentional, for example, a compromised CDN resource) which checks the location and sees it is your bank and changes it to a phishing site. You go back to the tab, expecting it to be your bank and log in and have compromised your credentials.
Postmessage
postmessage is an API which allows pages to communicate with each other, even across different domains. If postmessage
has been used on the parent and contains a vulnerability that could allow a new page to gain additional privileges.
Solution
Add rel="noopener noreferrer"
to your links to prevent window.opener
from being set unless you trust the property you are linking to.