window.opener and security – an unfixable problem?

If you know some JavaScript, you'll know that window.opener exists in popups created with window.open() to allow JavaScript in the popup to communicate with its opener window. You might not be aware that this property is also created for popups caused by target=_blank links and forms, but IE and Firefox do this. Popup -> opener communication is generally subject to the normal cross-domain limitations, so that a page from another domain can't for example change the DOM of the opener. However, it *is* allowed to change the address of the opener window by setting window.location, even cross-domain !

This opens up some security worries. Ideally, we would like to prevent cross-domain opener.location setting (for example, an abuse case might be clicking a link in an E-mail that opens in a popup and navigates the main window away from your mailbox to a page you would rather not visit..) but I guess that we would see considerable breakage on the Web if we tried that.

We have tried to let sites sort of "opt-out" from having window.opener defined in the popup window by not setting the window.opener property if the popup was created by clicking a link with target="_blank". That way, your webmail could simply give external links a _blank target attribute and protect the inbox from malicious navigation changes.

Enter KfW Förderbank.. Load page and click "Abschicken" at the bottom. Try the link in the popup. Nothing happens because that functionality depends on "window.opener" being set after submitting a target=_blank form.

Perhaps this problem isn't fixable at all? Or perhaps we should ask the Web API guys to enhance window.open with a new argument that will create a popup without window.opener?

[Edit: trying to "bump" post since there are no comments yet, changing date :p ..]

Advertisements

9 thoughts on “window.opener and security – an unfixable problem?

  1. hm…my FF(1.5.0.10) tells me that "opener.location.href is not a function"and the script you gave as an exemple only works in IE6 for me.my 2 cents:target="_blank" should not have an opener. Usually target="_blank" is used to mark a link that takes me off site. I never had to use it on a form before, but then again i never had to make a website for a bank…

  2. I find this issue a mild flaw. The location can be set. No other property of the js environement can be read or written.

    target="_blank" should not have an opener. Usually target="_blank" is used to mark a link that takes me off site. I never had to use it on a form before, but then again i never had to make a website for a bank…

    That's right but IE and Moz do this, and therefore it's causing problems for Opera.

  3. Per site preference that turned off by default?…And turned on by default for known trusted sites that depend on that…BTW, iCab also has this problem.

  4. What about giving the information about security issues in IE+FF to the appropriate parties? If this is listed on Secunia probably even IE will close this pishing whole after some months.update:funny, the link works (opens the page in the same tab) using middle-click (which is set to open in background tab) – of course a useless empty tab is opened in background (javascript:opener.window.location.href = "http:// …)even more funny: CTRL+SHIFT + Click on the link doesn't work nor does SHIFT+Click

  5. Hi ResearchWizard,there's this phrase Chris Wilson on the IE team likes to use: "don't break the web". Since Opera has just proven that tightening the security policy ever so slightly has broken something (and to make it really effective, the policy should be even stricter), other browsers are sadly not likely to want to go there. As it stands, it is debatable whether this is simply a feature the web relies on or a security hole.. I don't know what Secunia would make of it but I assume they would call it a feature since many sites rely on it.If phishers start abusing this to steal you Google Account or Live.com login, for example, we're of course going to regret it. Guess that's what you call being between a rock and a hard place 😦

  6. Hi Hallvord,that's the point that the solution I thought of has nothing to do with Opera itself. But I saw a slightly different possibility towards

    other browsers are sadly not likely to want to go there

    and

    being between a rock and a hard place

    It seems I need the long version to explain this.Microsoft regularly brakes single sites with updates of IE, esp. if some ActiveX isn't working any more (I'm too lazy now to search for details). And for IE7 a lot of designers had to change their pages (preferably during the long beta stage). From time to time even software applications don't work after a Windows update. The point is: there will be updates or workarounds for the applications and the real web will quickly adapt to new behaviour of IE. It's the same way (nearly) everybody works around stupid IE bugs all the time. Although Microsoft tries to cause as few trouble as possible with their changes, IE sets the rules for the real web (luckily Firefox reintroduces standards compatibility) and often the site changes will be quick enough to go unnoticed.

    I don't know what Secunia would make of it but I assume they would call it a feature since many sites rely on it.

    AIFAK Secunia is not Microsoft. I think Secunia is not interested in features but only in security issues. And I hope IE could get some pressure by third parties like Secunia to fix security issues. For this topic the question is: is there a security problem in real world with window.open() and target="_blank"? I am not familiar with this speciality and I rely on your excellent knowledge. I think for Secunia (and other's) no real exploit of Google or other accounts is needed. A proof of concept that it could be used for XSS attacks in a test case should be enough. And maybe some thoughts about how relevant it is in real world – as far as I understood it might be pretty easy to have a systematic and directed attack if you control the real page (the pishing page would only work if opened from the real page). This wouldn't be a substantial danger for banking sites but for any page you can put your own content that also contain more sensitive information on another level. This could be inside an email opened in a Webmailer, a comment of a blog or on some of the popular social network pages. So could you deliver some working hack for Gmail, WordPress or Myspace (et al)? I think target="_blank" is often used to keep the original page open, but I have no idea what you could control on the original page and I'm not really interested in learning how to write an exploit 😉 (I'm limited to the stage before: make the concept, define the requirements and provide the functional design. IMHO my thoughts are part of this just missing the malicious details).By the way: could the middle click behaviour provide a hint towards a quite different but working and secure solution: just ignore to open the page in a new tab would prevent the (not any longer open) page to be controlled by the new page. In other words: simply open the page in the same tab (simple for the user but probably not easy to define and implement and of course this will still break the feature to change the original webpage – I don't know whether this is also available in real world).Christian

  7. I experience this too and although it may not be suitable for everyone, i did fix the problem. My issue involved a form being submitted with target="_blank" and the new window would attempt to redirect the parent window and then close itself. Here is the script from the spawned window:

    self.opener.window.location.href = "emplTimeSheet.asp"; self.close();

    Here is the rememedy I went with:

    (function() {
      if (top == self) // create iframe and make all forms target it
        document.addEventListener('DOMContentLoaded'
          ,function() {
            var doc = document, frame = doc.createElement('iframe'),
                els = doc.selectNodes('//form[@target="_blank"]');
            if (!els.length) return;
            frame.id = 'frame';
            frame.style.display = 'none';
            doc.body.appendChild(frame);
            for (var i = 0, el; el = els[i]; i++)
              el.setAttribute('target', 'frame');
          }
          ,false
        ); // if in the iframe, redirect parent
      else if ((location.pathname == '/TSForEmpConf.asp') && (top != self))
        opera.addEventListener('BeforeScript'
          ,function(e) {
            e.element.text = 'top.location.href = "emplTimeSheet.asp"'; 
          }
          ,false
        );
    })();

    It obviously won't work for everyone, but if you have anthing similar you can give it a try.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s