10

While I was testing the SOP, i came to this scenario two documents has a relationship with the same domain as i would expected and it throws an error when i try to get the location.

To reproduce the problem:

  1. Open https://www.google.com
  2. from the console let opened = window.open("https://www.google.com")
  3. from the same window do opened.location.toString() which will return the correct location
  4. from the second tab's console do document.domain = "www.google.com"
  5. from the first tab do opened.location.toString() and you will get an error

    Uncaught DOMException: Blocked a frame with origin "https://www.google.com" from accessing a cross-origin frame.
    at <anonymous>:1:12
    

Can anyone explain this strange behavior?

Nino Filiu
  • 10,020
  • 6
  • 40
  • 53
as77c
  • 105
  • 1
  • 6

3 Answers3

6

This error is not a bug. The same-origin policy is a security mechanism that ensures that window objects only have access to the informations they are authorized to get. In your case, this includes having access to opened.location.

Upon creation, both tabs have the same origin, which allows the first one to access opened.location. But after the call to document.domain='www.google.com', they don't anymore.

"What? But in both tabs, window.location.origin are identical"

Yes, but it is a little bit more complex. The origin is defined by the scheme/host/port tuple, see @TheUnknown's answer for more details. The scheme and host stay the same all along, and they're the one included in the string of window.location.origin.

The tricky thing to know is that any call to document.domain, including document.domain = document.domain, causes the port number to be overwritten with null, therefore causing a difference in the two tabs' origins, and preventing them from communicating informations like opened.location with one another, thus the error.

Informations extracted from MDN's guide on same-origin policy

Nino Filiu
  • 10,020
  • 6
  • 40
  • 53
  • In both instances, the port is null - both before and after setting it. The port is only set if it is explicitly in the domain – Derek Pollard Mar 29 '19 at 21:06
  • I beg to differ. Running `document.domain = document.domain` in *both* tabs allows the first one to still access `opened`'s fields – Nino Filiu Mar 29 '19 at 21:10
  • From your own link, *"Two URLs have the same origin if the protocol, port (if specified)"* – Derek Pollard Mar 29 '19 at 21:14
  • Port is not specified in either place, so the restriction does not apply – Derek Pollard Mar 29 '19 at 21:15
  • The linked MDN *specifically* precises how and why setting `domain.domain` can result in permissions errors. It also explains that *The port number is checked separately by the browser*, which might explains this behavior. – Nino Filiu Mar 29 '19 at 21:24
  • `typeof window.location.port` does not change before or after either – Derek Pollard Mar 29 '19 at 21:30
  • a great way to test your theory would be to try and replicate the issue on IE - if it is the port, IE shouldn't have the issue since it doesn't do a port check – Derek Pollard Mar 29 '19 at 21:32
  • *The port number is checked separately by the browser* might point to the direction that the same-origin checking cannot be replicated by the value in `window.location.port` – Nino Filiu Mar 29 '19 at 21:35
  • _Port IE doesn't include port into same-origin checks._ – Derek Pollard Mar 29 '19 at 21:37
  • Give it a try in IE, I would but I'm on the train. It would confirm your theory – Derek Pollard Mar 29 '19 at 21:40
  • is there a way to specify the port? I tried location.port in both windows and they are empty. – as77c Apr 04 '19 at 06:54
4

First, I would recommend, you read Same-origin Policy.

The same-origin policy is a critical security mechanism that restricts how a document or script loaded from one origin can interact with a resource from another origin. It helps isolate potentially malicious documents, reducing possible attack vectors.

Two URLs have the same origin if the protocol, port (if specified), and host are the same for both. You may see this referenced as the "scheme/host/port tuple", or just "tuple". (A "tuple" is a set of items that together comprise a whole — a generic form for double/triple/quadruple/quintuple/etc.)

In this particular case, you open a window with HTTPS protocol, however when you set the domain, the protocol is changed to HTTP, see image below:

protocol has changed

As per 1, if the protocols are not the same, then its a violation of the principle and hence you get the error

Uncaught DOMException: Blocked a frame with origin "https://www.google.com" from accessing a cross-origin frame.

cross-origin is the keyword here.

Also, check out this SecurityError: Blocked a frame with origin from accessing a cross-origin frame for more details.

Polynomial Proton
  • 4,421
  • 15
  • 37
0

This will be a bit uninformative (just states facts), nevertheless:

  • After you change domain in window B, window B stops accounting window A as opener.

  • Since window A is no longer considered an opener of window B, the access is prohibited.

This makes me think, that altering document.domain is considered potentially insecure and is "punished" by orphaning the child window.

haldagan
  • 893
  • 4
  • 16