Web Security: add rel=noopener to external links

Don't touch my tabs! (rel=noopener) is a Firefox add-on that adds rel="noopener" to external links on sites open in Firefox automatically. Noopener_by_default is a userscript that does the same for links.

Did you know that sites that you load by clicking on links may manipulate the page the link was posted on?

Imagine two HTML pages: index.html the first page with a link pointing to omg.html. When you click on the omg.html page on index.html, that page gets open in the browser in a new tab if the target blank attribute is added to the link (the latter is a requirement for this to work).

The page omg.html may use the window.opener property to manipulate content on index.html. Since this happens in the background, it often happens without the user noticing a thing about it.

In worst case, this may be used to display a fake login page on the source web page to phish user data.

The link attribute rel="noopener" will set the window.opener property to null, so that target sites won't be able to manipulate the originating page.

You are probably wondering why browsers are not simply adding rel="noopener" to all links that open in new tabs and be done with it. Browser makers state that this will break certain sites and services on the Internet.

You can test it for yourself on this web page. Click on the first or second link on the page to get started. It opens a new page in a new tab. When you go back afterwards to the originating page, you will see that it has been modified by the target page.

Solutions

rel noopener browser issue

There are a couple of solutions that prevent this type of manipulation:

  1. Middle-click on links to open them instead of left-clicking on them.
  2. Install the Firefox add-on Don't touch my tabs! (rel=noopener). It adds the rel="noopener" attribute to all external links, but not same-origin links. Please note that this works from Firefox 52 on only, as this will be the version of Firefox that supports rel="noopener).
  3. The userscript noopener_by_default adds rel="noopener" to any link that uses target="_blank".

The rel="noopener" attribute works only if the browser supports it. Chrome, Opera, Vivaldi and Safari do already, Firefox will with the release of Firefox 52 on March 7, 2017.

Middle-clicking on links works regardless of that.

Side note: We add rel="noopener" to links here on Ghacks so that you are safe from this when clicking on links here on the site.

Summary
Article Name
Web Security: add rel=noopener to external links
Description
The guide explains how to add the link attribute rel="noopener" to links to improve the security of your browsing session.
Author
Publisher
Ghacks Technology News
Logo
Please share this article

Facebooktwittergoogle_plusredditlinkedinmail



Responses to Web Security: add rel=noopener to external links

  1. Tony January 24, 2017 at 12:24 pm #

    At least for cross-origin cases, the fix needs to be integrated into the browser by default.

    Have the browser manufacturers identified how many sites really need this functionality?

    Perhaps those sites could use a different implementation.

    The avenue for abuse seems to be much wider than the avenue for actual need.

    • fifox January 26, 2017 at 10:49 pm #

      Totally agree. I'm curious if there are any good examples of sites that uses this "feature" non-maliciously and that could not do what they want to do without it.

  2. Jeff January 24, 2017 at 12:38 pm #

    Thanks Martin! So very useful. What about Chrome or Opera?

    Update: Found an extension myself: https://n0where.net/chrome-extension-blank-protector/

    • Martin Brinkmann January 24, 2017 at 2:51 pm #

      Thanks Jeff for finding one and posting it.

    • Brent R Jones January 24, 2017 at 6:30 pm #

      I can't get this Chrome extension to work on the test pages. I did get it installed OK. Maybe I need to close browser to initially enable it.

  3. Tom Hawack January 24, 2017 at 12:56 pm #

    "Please note that this works from Firefox 52 on only, as this will be the version of Firefox that supports rel="noopener)."

    Thanks Martin for mentioning this and a pity the developer of the 'Don't touch my tabs! (rel=noopener)' Firefox add-on doesn't : I had tested the add-on with Firefox 50.1 and was surprised to notice on the test page above mentioned that it was inefficient...

    Users of the famous 'Tab Mix Plus' Firefox add-on can limit the risks of links that uses target="_blank" by checking the add-on's setting 'Options / Links / Open links with a target attribute in current tab'

  4. earthling January 24, 2017 at 1:59 pm #

    The test-page doesn't seem to work in a private window.

  5. earthling January 24, 2017 at 2:46 pm #

    This simple userscript prevents tampering with window.opener, so you don't have to rely on web-admins to properly protect their links:

    // ==UserScript==
    // @name Clear window.opener
    // @description Prevents tampering with window.opener.
    // @namespace localhost
    // @include *
    // @run-at document-start
    // @version 1.0
    // @grant none
    // ==/UserScript==

    if (window.opener != null)
    {
    window.opener = null;
    console.warn('Cleared window.opener!');
    }

    • Martin Brinkmann January 24, 2017 at 3:02 pm #

      That's cool, thanks for posting it.

    • Tom Hawack January 24, 2017 at 3:10 pm #

      Nice, thanks for sharing, earthling!
      Just tried the script on the test page mentioned in the article and it performed just fine.

      • earthling January 24, 2017 at 3:48 pm #

        "just fine" - JUST FINE you say??!
        Sorry that it doesn't bring you a coffee every time it clears window.opener! xD

        Kidding aside, my script is a lot more efficient than adding a parameter to every link on every page, of which you probably won't click 99% on anyway, AND you can even make it slightly faster if you remove/comment the console.warn() line. But since that is a negligible improvement and because some sites can break, it's probably preferable to have a console output if you need to troubleshoot a broken page.
        And it should work in every browser and version that supports userscripts.

        "Just fine" - pffff! ;)

      • Tom Hawack January 24, 2017 at 4:39 pm #

        @earthling ... I was searching for something less formal than "it works" :) ... Is "it does the job" more pleasant to your urban ears?!

        I note "you can even make it slightly faster if you remove/comment the console.warn() line" -- I won't remove it for the reasons you mention but it's good to know it wouldn't stop the script from running... just fine. LOL!

        I'd love to know what itches you with the "just fine' wording, in order to improve my basics of "English language and literature in the context of a new era and correlative cultures" ...

      • earthling January 24, 2017 at 5:22 pm #

        'I'd love to know what itches you with the "just fine' wording'

        If I asked your girlfriend "how is the sex with Tom?" and she would answer "well, he performs just fine.", would your urban ears like to hear THAT? :)

        But of course I was just joking because I know you like to joke around and you just gave me the perfect pitch to make a funny point and give me an excuse to explain that my script is basically the most efficient and best solution to date to deal with the problem at hand here IMHO (apart from blocking JS all together ofc). You know, lighten up the mood a bit since this is a really fucked up problem.

      • Pants January 24, 2017 at 5:30 pm #

        @earthling .. is this any faster? xD

        // ==/UserScript==
        (function() { "use strict"; window.opener = null; })();

      • earthling January 24, 2017 at 5:41 pm #

        LOL, now the smarty-pants shows up.
        It probably is but only because you don't have console output that way, or if you add it you would have console output ALL THE TIME!! Not the same, sis!
        I'm customer-friendly, you know?! I help people with troubleshooting! xD

      • Tom Hawack January 24, 2017 at 5:48 pm #

        @earthling, I was just wondering because as a Frenchman I miss English nuances sometimes. I know it was for a smile and that's great but in between a laugh and a smile are often nested a reference to something I missed.

        If a lady mentioned "just fine" to resume a night's odyssey with me I might indeed ask myself "not better than that?" ... never heard anything of the sort when it'd rather be 'Oh James, you are the king of the divan" ("James" when her fantasy is sacrificing her body to a secret agent in order to protect Mother Homeland!).

        Enough of my privacy- Your script does it and the WebConsole witnesses ir as well. That gives you the right to pay me a coffee, earthling. Congratulations!

    • Anonymous January 24, 2017 at 4:11 pm #

      Thanks too much!

    • Martin Brinkmann January 24, 2017 at 4:25 pm #

      I cannot get this to work somehow using Greasemonkey and the linked test page.

      • earthling January 24, 2017 at 4:39 pm #

        Hmm, that's weird. It definitely works for me and it also worked just fine for Tom.

  6. Foxes make me paranoid January 24, 2017 at 2:58 pm #

    Thanks Earthling...

    is that script sufficient to use in Firefox pre v52 (via Greasemonkey) ?

    • Martin Brinkmann January 24, 2017 at 3:15 pm #

      Should be, as it does not rely on setting the rel attribute.

      • Foxes...etc January 24, 2017 at 3:17 pm #

        Thankyou Martin.

    • Tom Hawack January 24, 2017 at 5:04 pm #

      @Martin, maybe hadn't you either cleaned the cache or reloaded the page with skip cache before using the script?

  7. Mu January 24, 2017 at 4:16 pm #

    Odd functionality. Well, at least it's safe with NoScript, since this relies on having scripts enabled on the site that hosts malicious.html.

    Shouldn't NoScript specifically deal with this even with scripts enabled though, like it does with many things ? Like, isn't it bordering XSS territory ?

  8. Sören Hentzschel January 24, 2017 at 5:08 pm #

    > Did you know that sites that you load by clicking on links may manipulate the page the link was posted on?

    Yes, there were a lot of articles about this topic in the last year. It's almost not possible not to know that if you read articles about web development. ;)

    You can use "noopener noreferrer" instead of only "noopener" to get the same protection in older versions than Firefox 52.

  9. Zackary January 24, 2017 at 5:58 pm #

    I don't get it. Why was this even possible in the first place ? What are legitimate uses for this functionality ?

    ///

    "There are a couple of solutions that prevent this type of manipulation:

    - Middle-click on links to open them instead of left-clicking on them."

    Take that, you multiple tabs nay-sayers! I middle click almost everything. I started a decade ago, partly because I prefer it that way in many cases and partly because I knew some web context is passed through a left click that is not passed through middle click. I think. That was a long time ago.

  10. earthling January 24, 2017 at 6:13 pm #

    @Pants,

    you don't happen to play TWD No Man's Land, do you?
    Because I raided someone named Pants recently, and boy, those defenders sucked xD

    • Pants January 24, 2017 at 6:29 pm #

      Nah ... not me. I haven't played an online game since .. ever. Used to be the life of the LAN party back in the late last millennium. Last game I played was when I bought my current machine in Dec 2011 .... it was five years ago in January and I wasted a month playing Skyrim .. eventually took an arrow to the knee

      • earthling January 24, 2017 at 6:49 pm #

        "eventually took an arrow to the knee" - lol, I remember that one, although I never played Skyrim myself.

        Ok, I assume you're just ashamed to admit that your defenders suck xD

        You should check out Dota 2 if you ever feel like playing a game again, it's for girls too ;)

      • Pants January 24, 2017 at 7:11 pm #

        https://en.wikipedia.org/wiki/Skyrim Release Date: November 11, 2011

        It's still installed, and I have a half dozen saved game points. I maxed out on a half dozen skills (archery, light armor, beauty, stealth, one handed weapons, make-up, cooking, ironing) and also lollied up to the max on extras such as all the archery specials. It also now takes me (exponentially) longer and longer to gain points that I'm currently at something stupid like a weeks solid play to level up one. Last save point is Jan 12th 2014 .. I guess I must have revisited it 3 years ago. January is holidays time, so I guess I was bored, which is atypical this time of year for me.

        The game I played prior to that was .. one of those RPG games ... Heroes of M&M VIIIIIII I think .. about 10 years or more ago .. and prior to that Baldur's Gate ... and way way back ... Pagan ( https://en.wikipedia.org/wiki/Ultima_VIII:_Pagan )

        I used to be a whizz in the 90's with doom and quake and stuff .. now I feel old. Thanks a lot earthling!

      • earthling January 24, 2017 at 8:06 pm #

        Oh yeah -- the good old quake days!
        I still play Quake Live (on steam) nowadays sometimes, with the old movement and everything. It just never gets old. Probably my all-time favorite game ever.
        Was never too much into RPG games so all those titles don't ring a bell for me.
        I was mostly into FPS games, but I also loved games like Commandos, Warcraft III, the earlier Tomb Raider games and Magic the Gathering. Today I only still play Dota 2 fairly regularly.

      • Pants January 24, 2017 at 8:44 pm #

        wot? no comment on my skillz - beauty, make-up, cooking, ironing

        Oh yeah .. getting OT .. but half-life & mods was a fave

  11. earthling January 24, 2017 at 9:15 pm #

    LOL, totally missed that, haha! Beauty seemed weird, must have skipped over the rest of the list at some point because I never played Skyrim and all those details didn't mean anything to me.
    To be fair, cooking was a thing in WoW, and ironing could just be a weird wording for doing things with Iron, you know ... forging. Make-up should have given the joke away but yeah I totally missed it, unfortunately.
    I used to be pretty good with spotting jokes but then I took an arrow to the knee.

  12. Rick A. January 24, 2017 at 11:02 pm #

    You say we should middle click instead of left clicking, but what about right clicking and selecting open in new tab? Martin? Anyone please answer.

    • Pointer January 24, 2017 at 11:18 pm #

      Should fix the problem. Try it yourself, the link provided is safe and does nothing bad.

    • Pants January 25, 2017 at 1:45 am #

      Right Click is I assume the same as a left click, except you are using a menu item. Middle click has special properties I think. You can always test it to find out :)

    • Rick A. January 25, 2017 at 6:34 am #

      @Pointer and @Pants - i don't know why i didn't think to try it out myself knowing i checked the website out earlier, talk about a brain fart, i was tired.......... Anyway, i tested it out and it works, right clicking and selecting open in new tab works just like middle clicking. You should put that in the article Martin as not everybody uses a mouse.

    • AAA May 22, 2017 at 1:12 am #

      LOL. You're funny! :D

      I use Simple popup blocker on Firefox to stay away from all those clickbait ads and popups, hate those popups on those free movie sites.

  13. Pointer January 24, 2017 at 11:25 pm #

    @Martin

    NoScript users can also fix it by adding a script surrogate. Though NS users are protected if scripts are disabled, they are not with scripts enabled unless they create the following about:config prefs as strings:

    noscript.surrogate.noopener.replacement
    noscript.surrogate.noopener.sources

    Their respective values should be:

    if(window.opener)window.opener=null;
    @*

    And that's it. Thanks Barbaz, moderator on NoScript's forum, for this tip. I don't know if NoScript will add this surrogate by default in the next version, do nothing, or if there will be a more subtle thing than what all current solutions do which is blocking the window.opener feature preventing good sites from using it too.

    • Martin Brinkmann January 25, 2017 at 6:19 am #

      That's cool, thanks for mentioning that Pointer. Would be great to see this implemented with an easier switch.

    • Jason January 25, 2017 at 5:51 pm #

      Wow, thanks for that Pointer. I can confirm that it works for me on the test page Martin provided.

      Just more reason to love NoScript.

  14. ams January 25, 2017 at 2:16 am #

    I would appreciate hearing how to achieve "when I open a page by middle-clicking a link, no 'referer' header is sent".

    I'm already using ff "ModifyHeaders" extension, but don't want to unconditionally suppress Referer: header.

  15. anonymous January 25, 2017 at 2:39 am #

    Would sandboxing prevent this?

  16. Paypal issue January 26, 2017 at 8:24 am #

    I didn`t have chance to inspect this in more depth, but the GM script prevented me from checking out with PayPal.

    After disabling the Greasemonkey script - my Paypal payment went through without problem.

    (this was the only change that had recently occurred so was able to quickly narrow it down between making online payments)

    Not the kind of thing which is easy to check and test :/

    • Tom Hawack January 26, 2017 at 11:29 am #

      I've just logged into my PayPal account flawlessly, with the earthling's GM script active. I believe it is that script you are referring to?

      • Paypal issue January 26, 2017 at 12:15 pm #

        Yes Tom, that`s correct.

        The issue occurred when I tried to actually 'check out' and purchase an item via PP (from ebay IIRC)

        As it was a "critical" moment I didn`t make notes of the error unfortunately.
        When I was redirected to a different page it had a red banner at the top.

        I went back a page, deactivated the GM script and then was able to chack out and pay normally, without error.

        This may not be an issue for anyone else, it may have been a coincidence or a specific issue due to my setup - but just wanted to make a note of it publically in case anyone else noticed the same behaviour.

      • Tom Hawack January 26, 2017 at 12:31 pm #

        I believe all incidents are worth being mentioned. I note your experience and will have it in mind next time I operate a transaction with PayPal. I'd love to test immediately but I have no purchase in view. Donating to Ghacks has been done for this year. Gosh, where could I spend a few bucks for testing a possible PayPal transaction issue with earthling's 'Clear window.opener' script? :)

        Seriously if the issue is confirmed then it'll be an exit for the script.
        Of course the opinion of the script's developer, earthling, is more than ever welcomed.

      • Lemming January 26, 2017 at 3:59 pm #

        The script to be modified to check for origin. Don't nullify window.opener if same origin... Paypal's issue is on paypal.com only right ?

        PS: Paypal are assholes. Fees are stupid high.

  17. earthling January 27, 2017 at 4:33 pm #

    "Seriously if the issue is confirmed then it'll be an exit for the script."
    Just add paypal to the list of excluded domains in Greasemonkey. No need to kick the script just because one site doesn't work.

    "Don't nullify window.opener if same origin"
    Feel free to change the script to fit your needs

    • Tom Hawack January 27, 2017 at 4:54 pm #

      Just add Paypal to the list of excluded domains in Greasemonkey... not to mention other domains if applicable.

      The developer of the 'Don't touch my tabs! (rel=noopener)' Firefox add-on states himself on the add-on's AMO page,

      "[...] when a hyperlink points to a web page hosted on the same domain name as the one you're on, it will NOT add the rel=noopener attribute."

      So it seems to me that Lemming's advice, "Don't nullify window.opener if same origin" makes sense.

      I don't code myself but if anyone can add this same origin as a filter for earthling's 'Clear window.opener' above it would be ... just fine :)

      I'm using your script, earthling, and have encountered no problem up to now. Which doesn't mean your script cannot be improved, right?

      • earthling January 27, 2017 at 6:29 pm #

        "Which doesn't mean your script cannot be improved, right?"
        I'm not convinced that it would be an improvement. You can't just assume that same origin is always safe.
        I've seen some truly mind-blowing vulnerabilities and exploits, and based on that I personally am certainly not gonna make that assumption.
        As for the reasoning behind that developers decision, the sentence you quoted is listed under "But won't this 'break my internet'?" so it's pretty clear why he implemented it the way he did. ie. security wasn't his main concern. I mean, I don't blame him, nobody likes zero-star reviews by people who can't watch funny cat videos anymore. But my script does exactly what I want it to do and I don't plan to "improve" it.

      • Tom Hawack January 27, 2017 at 7:03 pm #

        One thing is sure is that your script is efficient on the test page mentioned in the article, https://mathiasbynens.github.io/rel-noopener/

        On that test page is mentioned as well,
        "
        For older browsers, you could use rel=noreferrer which also disables the Referer HTTP header, or the following JavaScript work-around which potentially triggers the popup blocker:
        var otherWindow = window.open();
        otherWindow.opener = null;
        otherWindow.location = url;
        "

        Hence, as a plain-basic-illiterate wise guy I used your Clear window.opener script for it's frame and replaced the script with the one above, leading to :

        // ==UserScript==
        // @name Clear2 window.opener
        // @description Prevents tampering with window.opener.
        // @namespace localhost
        // @include *
        // @run-at document-start
        // @version 1.0
        // @grant none
        // ==/UserScript==
        var otherWindow = window.open();
        otherWindow.opener = null;
        otherWindow.location = url;
        //

        AND on the test page this second script doesn't do it :)

        I'm really basically proceeding, I understand nothin' to scripts, except a few operations within CSS, so all I can do is like trying to understand Chinese after a week's holiday in Japan :)

        Your script, 'Clear window.opener" does it, warns the console if applicable, and in case of a problem, as you said, just add the problematic domain to the script's exception list. I'll stick on that.

  18. earthling January 27, 2017 at 8:42 pm #

    Well, your script doesn't work because 'url' is never defined. And you're probably lucky that it's broken because you just created yourself a window.open bomb xD
    Try replacing url with a real url in quotes (otherWindow.location = "https://www.google.fr") and see what happens ;)
    I think FF has some protections to prevent too many window.open() calls, but idk if that also protects against nuking yourself with a GM script.

    • Tom Hawack January 27, 2017 at 9:02 pm #

      It's not "my" script! As I wrote above I simply copied it from https://mathiasbynens.github.io/rel-noopener/ ...
      Anyway it was for testing on that testing page only. Removed. But it is mentioned :
      "
      For older browsers, you could use rel=noreferrer which also disables the Referer HTTP header, or the following JavaScript work-around which potentially triggers the popup blocker:
      var otherWindow = window.open();
      otherWindow.opener = null;
      otherWindow.location = url;
      "

      So I don't understand and I won't try to given I know nothing in scripting.

      Thanks for your reply.

      • earthling January 27, 2017 at 9:34 pm #

        I only wanted to explain that those lines of code don't work when used in a GM script and that you almost accidentally turned it into a popup bomb.
        It was never my intention to insult you or make fun of you. If it came across that way to you, I apologize.

      • Tom Hawack January 27, 2017 at 9:52 pm #

        @earthling, I wasn't at all in that scenario, I mean I never felt any fun on my back! Wow, we've got a communication problem :) I just meant to explain what had let me to this nonsense piece of code, not to complain about your explanation! No problem, none!

        Back to one of my favorite French TV series, "Cherif" :)

        No problem, earthling, smile :)

  19. Alex2 February 2, 2017 at 7:50 am #

    Are the top links of https://eztv.ag (such like "Home" or "Countdown List") using this security issue?

    After clicking around 3 times the top links something like below appears....
    "javascript:window.opener=null;setTimeout(function(){window.location.href='https://onderlea.info/S3djWTl0URcwXXZBU2APek9FK1wvSlJ/WCkDXmsfPUpSdwh7WVZtF39RFmQAKBZaO198QltsDXhBB2EBKBRTP1pzEVc4CS1HBm4JLlEFKgR6UQo/BHtREDQEf0ZFMgQ4HwwuSm5FUzZXJx4NPBx5RxAxVjxSUWlVIgQXfAt7AwwrSy4ZFyoceUcGI009UlFpSi4FCjxKbQUGPwQjAxcpSm5EInwLDVJRH1wxAxV3WCxSUR9KIxgUNVA4A0Zrf20UF2QIbRQXOgR8URAtSnZGRTZKOUoGI009WQI+HzsFDWQJbQ=='},250)"

    Question - Shouldn't this be fixed by default for all browsers??

Leave a Reply