Are you making your website vulnerable by adding target="_blank"?
Or, are you compromising the performance of your website? Okay, first, let me show you one example!
Or, are you compromising the performance of your website? Okay, first, let me show you one example! (Press back to come back to this blog after clicking the link.)Click this link to see the DEMO!
This issue has been fixed now in recent browsers. Ref
If you didn't know this before, I'm pretty sure you're more than convinced that using
target="_blank" alone is dangerous for your website. And Indeed, it is one of the most underestimated vulnerabilities.
When I saw this happening for the first time, I couldn't believe it. It was unbelievable. How did I not know about this? I've seen popups filling up the forms, redirect the parent pages, etc. But I didn't notice that these data can actually be accessed by the cross-origin websites.
Let's see when people generally use target="_blank"!
- If they don't want their users to leave their page.
- They want to differentiate between internal and external links.
- They're having a page with infinite scroll and don't want their users to lose the scroll position.
- If there is some form and they want to prevent the data loss.
These are the major reasons and I'm not in favor or against of any use case because it totally depends on the situation. All of them are both good and bad in different situations.
How can attackers exploit your website?
One of the use cases that comes to my mind after seeing this is the PHISHING!
In general, if some attacker wants to compromise your website's data, he/she will redirect your page to a clone of your website. And that might lead your users to compromise their credentials or any other sensitive data or information.
Even if someone doesn't want to exploit your website, they can significantly harm the performance of your website. We'll talk about this later in this blog.
Fortunately, almost all browsers don't support to access the DOM if the domain of the website is not the same. But still, we do have access to the window object of the parent website. But I've read some blogs and some discussions saying they've seen cookie and session hijacking using this vulnerability. And to be honest I've tried that and I couldn't do that cross-origin in the latest browsers.
You can check the features and vulnerabilities in this GitHub repository and don't hesitate to make a pull request if you want to add some more details or vulnerabilities.
Let's see how this works!
If you take a look the code of the anchor tag above (using inspect), there is nothing suspicious about that link. It has only 2 attributes - src and target. But the magic happens after clicking the link.
After clicking this link, the new window gets the whole reference of the window object of the parent website inside
window.opener. The data can be fetched and modified from the child, and also we can do the same from the parent only if we use
window.open() to open the link.
You can also check this by executing
window.opener inside the console of the child window. To change the parent window's location, you can run this command:
window.opener; window.opener.location = 'https://gosink.in';
How can it affect performance?
If you open the links with target="_blank" alone, it runs on the same process id. You can also check this in
Task Manager, or
And if you've some knowledge of native programming, you'll agree that if you can get the same PID, you can get all the access that parent process has, and you can also traverse through the memory using pointers (Not sure about WebAssembly).
What is the solution?
The solution is pretty simple. We can prevent this by just adding
rel="noopener" to our anchor tag. This makes window.opener null. But still, it lets the other page know from which page a user came from. To prevent that you can use
rel="noreferrer". If you use noreferrer you don't need to set noopener for the most browsers but personally I prefer to add both of them to be safe:
Of course not! window.open() does the same job. But you can set the window.opener to null like this:
const newWindow = window.open('https://gosink.in'); newWindow.opener = null;
You might be using this anchor tag properly but if some external modules/libraries are not using this properly, it may lead to compromise these things. So better check your website using Google Lighthouse before publishing your website to production.
I generally see no use case of using target="_blank" to enable the communication between a parent and its child window. And technically, it leads your website to perform poorly and some times you may end up compromise your users' data. So it is the best practice to use at least rel="noopener".