Edit: We took the behavior to point out this flaw in Facebook because, even though interesting, it was getting to be annoying because Facebook was not fixing it. Oh well. Read this article and imagine everything that is described here. We're still playing around with this sometimes for fun. The overall issue is still alive and well in the web in general.
If you use the target="_blank"
attribute on a link, and do not accompany it with a rel="noopener"
attribute, you are leaving your users open to a very simple phishing attack. We run a script that takes advantage of this issue in order to notify users when they come from a site that has not protected them from the vulnerability.
if (window.opener) {
window.opener.location = "https://dev.to/phishing?referrer="+document.referrer;
}
I believe that the majority of websites do not deal with this issue properly, but I was surprised to find that Instagram.com was one of them. We just recently started an Instagram account for @ThePracticalDev and that is when we noticed the problem. If you click the dev.to
link in our profile, and then go back to the original tab, you will see what I mean. Twitter also does not protect against this vulnerability on Safari, not Chrome or Firefox. They do not use rel="noopener"
so it seems like the script they are using to accomplish this security is not working properly in Safari.
Edit: Because Instagram fixed the issue after this post went up I have changed the following example to Facebook Pages.
To clarify
- Visit The Practical Dev Facebook page.
- Click the
dev.to
link in the profile. This opens a new tab or window. - Observe that the original tab has migrated to this page.
When a website uses target="_blank"
on their links in order to open a new tab or window, that website gives the new page access to the existing window through the window.opener API, allowing it a few permissions. Some of these permissions are automatically negated by cross-domain restrictions, but window.location is fair game.
But wait, there's more
Not only is this an issue with phishing attacks, it is also a privacy concern because the newly opened website has ongoing access to the browsing location of the original tab. It can poll for this information and get the answer. Thankfully this behavior seems to fall under the cross-domain restrictions, so while I might gain access to certain ongoing information you might not expect me to know, there are sane restrictions that should likely apply to the entire spec.
Edit: When I first wrote this, I proposed a browser-spying scenario where a bad-actor could spy more thoroughly on a user's browsing history. I think that was inaccurate, so I modified the statement.
In order to restrict the behavior window.opener
access, the original page needs to add a rel="noopener"
attribute to any link that has target="_blank"
. However, Firefox does not support that tag, so you should actually use rel="noopener noreferrer"
for full coverage. Some amount of prevention can be acheived through scripting, though, as observed with Twitter, this seems to fail on Safari.
var otherWindow = window.open();
otherWindow.opener = null;
otherWindow.location = url;
This script suggestion came from a good article on the subject.
This issue is not well-known, and is totally underestimated. This has been brought up in a Web Hypertext Application Technology Working Group mailing list. In my opinion, the risks of this browser behavior far outweigh the potential benefits. Either way, there are no excuses for Facebook and Instagram and Twitter to have overlooked this.
I'll have more to say about this kind of thing in the future. Follow me (@bendhalpern) or @ThePracticalDev on Twitter if you are interested.
Top comments (12)
I just tried on Facebook, Instragram, and Twitter and they all seem to be fixed.
Not really... :)
steemit.com/security/@gaottantacin...
Affected browsers and social media platforms:
Chrome: Linkedin, ..
Chrome for Android: Facebook, ..
Edge: Facebook, Linkedin, Twitter, ..
Firefox: Facebook, Linkedin, ..
Opera: Facebook, Linkdein, ..
Safari: Facebook, Linkedin, ..
That is brilliant post.
Very well explained. I didn't know that vulnerability.
This article has some real life examples.
And now you can imagine some really bad attack.
I redirect to a Facebook like website I own that said "You've been disconnected, please reconnect". And boom, you have the user password.
Just brilliant.
So it is just vital to add the noopener value.
Is this vulnerability only exploited on pages where users submit or upload information? The reason I'm asking, a site I'm assisting, uses target="_blank" on many pages but most of the pages are only displaying information and user's are not submitting or uploading content.
It's only really a thing if you can't fully trust the pages you're linking out to. And as described, there are ways to mitigate this to a good extent.
Not sure if they fixed it in all social networks, or dev.to doesn't have the opener script anymore. I've tried a jsbin but didn't work either.
Is this vulnerability only exploited on pages where users submit or upload information?
Surely this is fixed now?
Thank you for sharing and explaining in detail. We'll make changes to the site.
Thanks Ben, literally a life saver
Some comments may only be visible to logged-in visitors. Sign in to view all comments.