6

Browsers typically don't allow a child tab/window to close its opener with script. And yet they do allow the child to alter the location of the opener tab/window.

This leads to a curious workaround whereby you can create a page that does nothing but close itself with script as soon as its loaded, and then change the location of the parent tab/window to this new page, effectively closing it.

Which leads me to ask, what security issue lead to disabling the ability to close an opener tab/window, and does this workaround effectively create a back door?

  • I don't know if you will get any definitive answer as to why this choice was made by the browser developers (opinions). but my guess is in the one case closing tabs/windows is/was an annoyance and was abused and in the other case navigating via changing locations was convenient and perhaps less abused. – KnightHawk Aug 12 '16 at 16:42
3

Browsers typically don't allow a child tab/window to close its opener with script. And yet they do allow the child to alter the location of the opener tab/window.

This is not entirely accurate. If you read the quoted MDN text more carefully, it is actually referring to the opening of the parent, not the relationship to its popup. The actual restriction you are probably running into is:

  • Scripts may only close windows were originally opened by script.

So in your specific example, the popup was opened by a script, but the opener was opened by a user, and therefore the opener cannot be closed by either itself or the popup.

Imagine a scenario where there are two popups

  • User-opened tab (cannot be closed)
  • Popup 1 (opener is user-opened tab)
  • Popup 2 (opener is popup 1)

Popup 2 can close popup 1 in this scenario.
However, popup 1 cannot close the user-opened tab because that violates the rule above.

  • In Chrome & Firefox, it does not matter whether the popups are same origin as their openers. The popup can change the location or close the opener as desired, subject to my first point above.

  • In IE11, the popup can close the parent, but cannot change parent.location unless it it meets Same Origin policy. (results in new popup if you try)

Also, I'd like to clarify that any opener can close its own popups or change their location without restriction. Access to the popup contents is still subject to Same Origin policy for security reasons.

This leads to a curious workaround whereby you can create a page that does nothing but close itself with script as soon as its loaded, and then change the location of the parent tab/window to this new page, effectively closing it. ... does this workaround effectively create a back door?

To answer your question directly, there is no such workaround. The linked example will produce the error:

Scripts may not close windows that were not opened by script.

Unless you are in a 2-popup situation as I explained above, in which case the popup could just close its opener directly. The workaround would be unnecessary in that case though.

  • I don't think you're right here. Firefox, for example, does not allow a child tab/window to call close() on its opener, only the opener can close the child. Even if they are of the same origin. However it will allow the child to change the openers location. – AntonChanning Aug 12 '16 at 20:04
  • "does not allow a child tab/window to call close() on its opener" Where did you see this? I suspect it was oversimplified. The exact rules used are ● outlined in my answer. My testing indicates that children can close their opener if they meet the rules outlined. – Bryan Field Aug 12 '16 at 21:29
  • See developer.mozilla.org/en-US/docs/Web/Security/…, Same-Origin Policy allows cross-origin Read/write access to window.location. – Alexander O'Mara Aug 17 '16 at 6:24
  • 1
    Sorry. I think you are right after all. It seems that I was getting confused because my parent was itself opened in a tab, so there were actually three levels of parent-child tab. The top level parent couldn't be refreshed this way. I found out it was uneccessary coupling anyway. Better to put the child in a variable and use the onunload and onbeforeunload events. – AntonChanning Nov 14 '16 at 10:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.