TLDR:
Checkout the implementation example here:
Live Demo
Let's Open a url in new tab from within our website
HTML WAY
<a href="https://malicious-domain.netlify.com" target="_blank">Visit Malicious Website!</a>
Okay, here we have a href attribute to a malicious website and target as _blank attribute to make it to open in a new tab.
Let us say that, the user clicks on "Visit Malicious Website!" from the above code. He gets redirected to the malicious website in a new tab.
The flow seems so plain and simple what's the possible Security risk that the user has here?
- The user is redirected to a domain from your page.
- At this time, the browser attaches all your
windowvariable's content of your current website towindow.openervariable of the malicious website.- This is done by Chrome and Firefox browsers which has one of the largest user base.
- So now the malicious website has access to your website's window, which obviously opens up a security loop hole in redirection of this method.
- Now the malicious website once it has access to your website's
windowvariable throughwindow.openerit can redirect your previous website to a new Phishing website which could look similar to the actual website you opened and might even ask you to login again. - The above change can be done in the malicious website by just writing the following code
if (window.opener) {
window.opener.location = 'https://www.dhilipkmr.dev';
}
- So the Innocent users get caught in this trap and would provide the login details which could be exposed to the attacker.
How do we avoid this?
A simple way is to add a rel attribute with noopener to the <a> tag.
<a href="https://malicious-domain.netlify.com" rel="noopener" target="_blank">Visit Malicious Website!</a>
What does it do?
-
rel="noopener"indicates the browser to not to attach the current website'swindowvariable to the newly opened malicious website. - This makes the
window.openerof the malicious website to havenullas its value.
So be careful when you navigate your users to a new domain that is not maintained by you.
Not always we open a new tab with a tag there are cases where you have to open it through executing javascript's window.open() like below,
function openInNewTab() {
// Some code
window.open('https://malicious-domain.netlify.com');
}
<span class="link" onclick="openInNewTab()">Visit Malicious Website!</span>
Here there is no mention of noopener so this results in passing window of the current website to the malicious website.
The javascript Way!
How to handle such cases when new tab is opened through js?
function openInNewTabWithoutOpener() {
var newTab = window.open();
newTab.opener = null;
newTab.location='https://malicious-domain.netlify.com';
}
<span class="link" onclick="openInNewTabWithoutOpener()">Visit Malicious Website!</span>
Here,
- We have opened a dummy tab through
window.open()which opensabout:blank, so it means it has not redirected to the malicious website yet. - Then we modify the
openervalue of the new tab tonull - Post that we modify the new tab's url to the malicious website's url.
- This time, again
openerwould have been null, due to which it cannot access thewindowvariable of the first website.
Problem Solved.
But this method wont be possible in older versions of Safari, so we again have a problem.
How to fix Safari's issue?
function openInNewTabWithNoopener() {
const aTag = document.createElement('a');
aTag.rel = 'noopener';
aTag.target = "_blank";
aTag.href = 'https://malicious-domain.netlify.com';
aTag.click();
}
<span class="link" onclick="openInNewTabWithNoopener()">Visit Malicious Website!</span>
Here we mimic clicking on an anchor tag.
- We create
<a>tag and assign the required attributes then executeclick()over it, which behaves the same way as the link is clicked. - Do not forget to add
relattribute to the tag here.
Other facts:
- When you click
CMD + LINKon anchor tag, chrome, firefox and Safari considers makeswindow.openerof the malicious website asnull - However, on
CMD + LINKon an element where new tab opening is handled through javascript, the browser attacheswindowvariable and sends it to the new tab. - By default, the new version of Safari removes
window.openerwhen used with anchor tag for all cases, to pass thewindowinfo to the new tab you have to explicitly specifyrel='opener'
Checkout the live implementation example here:
Live Demo
None shall bypass your Security.

Follow me may be :P
Thats all Folks!!!


Top comments (7)
I've been using noopener and noreferrer for years now, but never really understanding why. Thank you for the understandable explanation.
Yes missed them!
Whenever the opener object is defined in the new website, both run with same event loop. (i.e) there is only one process handling both tabs.
May be the approach of creating anchor tag dynamically through js and clicking it is the best approach that considers all cases ,if we want to open the new tab through JavaScript
Thanks - I've seen the warning message to use noopener in gatsby before, but never knew why. Now I do!
😃😃✌️✌️
Very good to know, I've never come across this before. Thanks a lot :)
😃😃✌️
Weirdly,
window.opener.open()is blocked by chrome (if it's cross-origin), but notwindow.opener.location = <url>