Cross-Origin Resource Inclusion

This article discusses a new bug class that was introduced in XMLHttpRequest Level 2, how the bug manifests and some solutions to different problems.

HTML5 is a hot topic in web security today. Mostly because of how expansive it is in relation to older web specifications, but also because it introduces new concepts for web developers to misunderstand.

First, some concepts.

Asynchronous JavaScript and XML (AJAX) was introduced into the web platform as a simple way to make HTTP requests from JavaScript. It allows for parts of a web page to be updated dynamically without reloading the entire page. Originally, AJAX was used for continuously updating content only. Today, AJAX is used for everything.

Web 2.0 Design Trends have been changing drastically over the past several years. I make no claims to be any kind of web designer, but I do know how to develop code for the web and I am able to make simple observations. When you go to a bunch of websites and you see similar functionality on all of them, that's called a trend. Here's one specific trend I observed over the past several months.

Facebook and Twitter have started using URLs that look like this:

https://www.facebook.com/#!/TheJulianCohen
https://twitter.com/#!/HockeyInJune/lists/memberships

If we take a closer look at how this URL is used, we see that these websites first load a generic page that contains some JavaScript. Then, these pages use an AJAX request to pull down the page-specific content at /TheJulianCohen and /HockeyInJune/lists/memberships; the part of the URL that directly follows the #!.

We can call this an example of "improper" use of AJAX, because it is not necessary to pull down the unique content after the page has been requested. There are many other ways of implementing this that do not involve an asynchronous request. Whether or not this is functionality was introduced as a performance increase or an artifact of poorly designed frameworks is unclear. I do believe that this will always present a performance decrease, but with these new fast JavaScript engines, it's difficult to say definitively.

Technical Note: This functionality has since been removed from these websites because of the security issues we will discuss below.

Same Origin Policy (SOP) dictates that client-side scripts are confined to their originating site, this means that a script from one site cannot influence any other objects belonging to another. SOP has been implemented in modern browsers for a long time, but SOP was first standardized in XMLHttpRequest Level 1. XMLHttpRequest Level 1 dictates that XMLHttpRequest() follows SOP.

HTML5's new functionality.

Cross-Origin Resource Sharing (CORS) is new functionality of XMLHttpRequest Level 2 that allows XMLHttpRequest() to make cross-origin requests, directly violating XMLHttpRequest Level 1's SOP restriction. This is done for added functionality, so developers can asynchronously pull content from other domains. The specification dictates that Cross-Origin Resource Sharing checks the remote host to see if it allows cross-origin requests, and this is going to be the root cause of the security issues introduced.

Now, because scripts are allowed to interact cross-domain, we need to redefine Same Origin Policy.

  • Scripts are confined to their originating site

  • Documents are confined to their originating site

What do we mean by Documents? Every DOM object has a parent Document object. Scripts in one Document object, cannot interact with scripts from another Document object. This sounds good, but where is this line drawn?

{% highlight html %}

Read more