The "Same Origin" security policy

  1. Demo
  2. Can’t get but can set
  3. The document.domain exception
    1. Example
  4. IE exceptions to Same Origin policy
  5. Cross-window messaging
  6. Summary

The “Same Origin” policy limits the access of one window to another.

The reason behind that is security. If you have blabla.com in one window and gmail.com in another one, then you’d not want a script from blabla.com to access or modify your mail or run actions in context of gmail on your behalf.

The essence of the Same Origin policy can be formulated as: windows can work in contexts of each other only if they are from same protocol://domain:port, or, shortly, from same origin.

Note that the path part of the URL doesn’t matter anything.

These are from same origin:

  • http://site.com
  • http://site.com/
  • http://site.com/my/page.html

These come from another origin:

  • http://www.site.com (another domain)
  • http://site.org (another domain)
  • https://site.com (another protocol)
  • http://site.com:8080 (another port)

But there are a lot of important pecularities around it which are considered in this section.

Demo

Let’s see what happens if we try to access a forbidden window:

<iframe src="http://google.com" name="google" style="height:100px"></iframe>

<script> 
document.getElementsByName('google')[0].onload = function() {
  try {
    alert(frames[0].location)
  } catch(e) {
    alert("Error: "+e)
  }
}
</script>

Run the example above. It gives error, because it is not allowed to get a property from the window from another domain.

Can’t get but can set

The important fact is that it is not allowed to read from another origin, but some properties are writable. The most notable one is location.

From the example above we’ve seen that browser protects location of the window from different origin from being red. But we can set it:

<iframe src="http://google.com" name="google" style="height:100px"></iframe>

<script> 
document.getElementsByName('google')[0].onload = function() {
  frames[0].location = 'http://wikipedia.org'
  alert('Changed to wikipedia')
}
</script>

The example above, when run, will change the location.

Note, changing location.href will not work, because there is no read access to location properties. Only direct set works.

The document.domain exception

Another important exception for the Same Origin policy are third-level domains.

Say, we’ve got a window at a http://site.com and two iframes: the first comes from http://john.site.com, and another one comes from http://peter.site.com.

All of them can assign document.domain property to site.com, and then the same origin restrictions will be removed.

Note two important features:

  1. The new document.domain value must be within the same second level domain.

    You can change document.domain='site.com' on the page originating from my.site.com, but can’t do it if the page is at another.org.

  2. The document.domain should be assigned on all windows, including the main one. Even if the domain is already site.com, you still need to assign it: document.domain=document.domain will do.

Example

The example below loads two frames from subdomains:

<iframe src="http://*!*a.JavaScript.info*/!*/files/tutorial/window/a.html" name="a" style="height:40px"></iframe>
<iframe src="http://*!*b.JavaScript.info*/!*/files/tutorial/window/b.html" name="b" style="height:40px"></iframe>
<script>
  function work() {
    alert('work at '+location.host)
  }
*!*
  document.domain = document.domain
*/!*
</script>

By clicking on buttons, you can call methods from the parent or another frame.

Both iframes assign document.domain='JavaScript.info'. That’s why they can call each other.

a
<script>
  function work() {
    alert('work at '+location.host)
  }
  document.domain = 'JavaScript.info'
</script>

<input type="button" value="parent.work()" onclick="parent.work()">
<input type="button" value="parent.frames.b.work()" onclick="parent.frames.b.work()">

So, the document.domain allows different 3rd level domains to communicate with each other and with their common 2nd level domain.

IE exceptions to Same Origin policy

Internet Explorer poses two major exceptions.

The first one are so called “Trust Zones”. If both domains are in highly trusted zone, e.g both are corporate domains, then the Same Origin limitation is lifted completely.

The second one is port. Internet Explorer doesn’t include port into Same Origin components, hence the http://site.com and http://site.com:8080 are considered from the same origin and no restrictions are applied.

The exceptions described above are non-standard and not supported in any of other major browsers.

Cross-window messaging

All modern browsers support messaging between windows. The topic is very interesting and solid. It is discussed in a separate article Cross-window messaging with postMessage.

Summary

The Same Origin policy allows one window to access properties/functions of another one only if they come from same protocol, same port, same domain.

The exceptions are:

  • Window location is not gettable, but settable
  • Third level domains may use document.domain to change their domains to common second-level domain, and then they can access each other without limitations.
  • IE doesn’t include port into same origin requirements. Also it provides trusted zones.
  • Cross-window messaging.

Tutorial

Donate

Donate to this project