As a developer, you’re constantly reminded about security threats: Cross-site scripting, SQL injections, plugins or libraries being exploited etc. A lot of the threats can be hard to get your head around at times so when you see a phishing vulnerability that is extremely simple to do — it’s a little bit scary.
At the time of writing, every popular browser fails to protect their users…not to mention that pretty much every website you use also fails to protect you against the phishing vulnerability that I’m going to go through — including Facebook, Twitter and quite ironically, Medium.
If you’ve ever used HTML whatsoever you’ll be aware that when you want a link to open in a new tab you could do something like:
<a href="http://website.com" target="_blank">click here</a>
Looks pretty normal, eh? Well the bad news is that if a site displays user generated content that allows links to be posted (like Facebook for example) and opens them using _target=”blank” then it’s vulnerable to a very simple phishing attack.
How can this be exploited then?
Unfortunately, it’s easy enough. Let’s say that the link above was on a random site, like Facebook. So you’re on Facebook and you open up a new tab which is website.com. Now, on website.com you have these few lines of code:
if (window.opener) {
opener.location = 'https://facebookclone.com/login';
}
That’s it! This causes the previous tab from which you originally clicked the link on to change to facebookclone.com/login. Now imagine you’re brought to a login page that looks identical to the website you were just on and asked to enter in your login details. Keep in mind that the domain could be something much more similar to the site you were on, something like facebo0k.com. If you still don’t believe it view the example that I made late on a Saturday night to see how it actually works.
There’s so many ways that someone could use this vulnerability to steal your information. Thankfully the likes of banks, Paypal and so on don’t allow user generated content really so they are more or less okay — but you could easily get around this by sending someone an email and then change the first tab to be a login page for their email provider and then gain access to loads of their accounts such as Paypal.
What's the fix?
Again, it’s so so simple, but very few sites have actually done it (Instagram is the only site I know of that has fixed this up). Keeping to the same example as I showed earlier, the fix would be:
<a href="http://website.com" target="_blank" rel="noopener noreferrer">click here</a>
Yep, all it takes is to add in the rel attribute (which exists to tell you what relationship the website you’re on and the website that you’re about to open has with each other) and add in noopener (for all browsers but Firefox) and noreferrer (for Firefox).
The sad thing is that the developers behind Chrome and other popular browsers don’t have any plans to fix this. According to the HTML spec, this is the expected behavior so nothing is being done. 99% of the time following specs as a developer is the right thing to do, but when the spec is incorrect and leaving people vulnerable something should be done in my opinion.
I can’t even think of a proper use case for allowing a site (which mightn’t be the same as the one that you’re on) to alter your previous tab completely. The default behavior really should be using these rel values but it doesn’t look like this is going to happen any time soon.
1 line of code…that’s all it took.
$('[target="_blank"]').attr("rel", "noopener noreferrer");
This one line of code changes all links that open in a new tab to have rel=”noopener noreferrer” so that no site will be able to change the tab that you were just on.
On the same night that I made the example that I mentioned above of how target=”_blank” could be exploited I also made a Chrome extension called “No Opener, No Phishers” which you can get on Github or the Chrome Store.
One last thing for developers...
If your site allows people to post links (even if they don’t open in a new tab — they might do at some point in the future) then please make sure you don’t allow anyone to be phished so easily. If you want to learn more about rel=”noopener noreferrer” I’d recommend this post.