Archive

Posts Tagged ‘DOM Same Origin Policy work around’

Understanding the Web-Same Origin Policy, Restrictions, Purpose, and Workarounds

December 13, 2012 Leave a comment

Ken2

December 13th, 2012 | Ken Payson

Understanding the Web-Same Origin Policy, Restrictions, Purpose, and Workarounds

Sooner or later every developer will have to get or send data from his or her site to a site on a different domain. Recently, I was working on a bookmarklet which required communication between my company’s site and another domain. Whenever there is web communication between two different domains, it is necessary to understand the same origin policy of the web. Wikipedia summarizes the same origin policy as

“The policy permits scripts running on pages originating from the same site to access each other’s methods and properties with no specific restrictions, but prevents access to most methods and properties across pages on different sites.”
The thing to know and understand is that there are two origin policies. The “DOM Origin Policy” governs reading/writing via the DOM information in different windows. The “XmlHttpRequest Origin Policy” governs Ajax communications between different windows.

DOM Same Origin Policy

The same origin policy for the DOM disallows reading from or writing to a window if the window’s location is on a different domain. This prevents a number of attacks which could be used to steal user information. A simple example would be:

  1. MaliciousSite.com has a link on its page to mybank.com
  2. User clicks on link which opens mybank.com in a new window using javascript window.open
  3. MaliciousSite.com could then read and write to mybank.com through a reference to the mybank.com window.

XmlHttpRequest Same Origin Policy

The XmlHttpRequest Origin Policy disallows sending HTTP requests via the xmlhttp javascript request object to a site on a different domain, so “normal” Ajax with an endpoint on a different domain is not possible. There are workarounds to allow information sharing which I will discuss later. It is important to note that the XmlHttpRequest Origin Policy really exists to prevent a different line of attack than the DOM Origin Policy. XmlHttpRequest Origin Policy is trying to prevent Cross Site Request Forgery attacks (CSRF) attacks.
When an HTTP request is made, the web browser will send the cookies belonging to the requested domain. In particular, sites typically use an authentication cookie which proves that you are logged in to a site. Based on this, if there were no XmlHttpRequest Origin Policy, a CSRF attack could work as follows:

  1. User navigates to a bad site MaliciousSite.com
  2. MaliciousSite.com makes the blind guess that the user is also logged in on another tab to MyBank.com
  3. MyBank.com exposes data via web services to authenticated users.
  4. MaliciousSite.com uses the web services of MyBank.com to obtain information. The web services on MyBank.com return the requested data because the user is authenticated and the authentication cookie was sent with the Ajax request.

Work-Arounds
Just as there are “two” origin policies, there are two corresponding sets of “workarounds” which allow for communication between windows. Let’s take a look at these methods and see how they allow for legitimate communication without reintroducing the same security holes.

Working around the DOM Same Origin Policy
In order to work around the DOM origin policy, one should use window.postmessage(). This javascript method is now part of the HTML 5 standards but has actually been around for some time. It can be used with IE8+, and all modern version of FF and Chrome. The use of windows.postmessage is thoroughly documented on the web but can be summarized as:

  1. Get a reference to the window which you want to communicate with ex var win = window.frames[0].window
  2. The window receiving messages sets up an event listener for the messages that will be sent.
  3. The sender calls win.postmessage(dataMessage).
  4. For two way communication, event listeners are set up on both sides.

Window.post message does not allow for unauthorized sharing of information. Using window.postmessage requires both sides to be in cooperation on the messages structure and it requires the message recipient to accept messages coming from the sender. Using the earlier example, myBank.com would never be expecting messages from mybank.com and so even if mybank.com did have an event listener set up and methods for data sharing it would certainly ignore messages coming from any unknown location.

Working around the XmlHttpRequest Same Origin Policy

To work around the XMLHttp Origin Policy there are a few different options. The first thing you could do, if you want to use a data service from another domain, is simply create a proxy service on your site which calls the service on the other domain and passes back the data. This involves extra server side coding on your part, but it also requires no cooperation from the other domain. The next techniques that I will mention involve cooperation from the other domain in how their web services are set up. If the other domain isn’t “cooperating,” writing a proxy service maybe your only option.

If a site wants to expose services that can be consumed via Ajax from another domain, there are two established options, JSONP and CORS. The JSONP technique uses the fact that javascript files can come from different domains. JSONP service requests are structured as requests for the javascript file. If a site returns JSONP it is actually returning javascript containing a function which, when evaluated, returns JSON data. The JSONP technique works but it is a “hack.” JSONP services could theoretically still be a CSRF attack vector, though it is much less likely. JSONP is meant to be used with cross domain requests and JSONP services need to be implemented differently. Because of this, accidently exposing sensitive data via JSONP services is not a real concern.

CORS is a relatively new standard that address the need for cross domain Ajax in a more proper fashion. CORS stands for Cross Origin Request Sharing. All modern browsers can make Ajax requests to other domains so long as the target server allows it. A security handshake takes place using HTTP headers. When the client makes a cross-origin request, it includes the HTTP header – Origin – which announces the requesting domain to the target server. If the server wants to allow the cross-origin request, it has to echo back the Origin in the HTTP response header – Access-Control-Allow-Origin. The target server can establish a security policy to accept requests from anywhere or to only accept requests from specific domains. On the client, jQuery Ajax automatically supports CORS for cross domain requests. So, no additional coding on the client is necessary if you are using jQuery. We can see that CORS also makes CSRF attacks highly unlikely. If a site is checking for an authentication token with its web services, it will certainly not add an origin header for an untrusted domain.

In Conclusion

I hope that you found this brief introduction helpful. Understanding the rhyme and reason for the same origin policy should make the learning process easier when it comes time to dive into implementation details. Happy coding!

Ken Payson is a Senior .NET developer at LogicBoost, an agile software services and product development company based in Washington DC.