XMLHttpRequest Same Domain Stupidity

When using XMLHttpRequest, there's an annoying restriction saying that you may only request data from the original domain the page came from.

This causes problems when you need to, for whatever reason, access data from another domain. With web mashups becoming more and more common, this is becoming a large problem.

Simple examples of the concept would be embedding a live-updating Facebook widget or a Flickr photo-stream widget. Both would require pulling data from their respective domains - and due to the "same domain" request restriction, couldn't do it through XMLHttpRequest.

Fortunately, this problem has been addressed, using something like JSONP.

How does JSONP work? Well, simple: you send a bit of JavaScript to the remote server, which then responds with a JavaScript document that contains this code along with the data it requires.

Except that you still can't pull this using XMLHttpRequest. So instead, what you do is create a new script tag and set its src attribute to this new URL.

Thereby pulling in the code from the third-party domain. And executing it directly.

Which is far less secure than being allowed to use XMLHttpRequest to access third party domains could ever be. (Well, sort of...)

So, in order to work around a "security" feature, the idea is to purposefully open up a cross-site scripting hole.


A quick note on the "sort of" above: allowing XMLHttpRequest to third-party domains opens up the potential to allow cross-site request forgeries. But this can be solved by limiting third-party domains to "GET" requests and assuming the people running the third-party domains aren't complete morons.



"assuming the people running the third-party domains aren't complete morons"

Unfortunately this is a huge assumption that unfortunately has not been borne out in practice. A much safer assumption is that they are morons.

And that's a rather discouraging thought.

The thing is, allowing XMLHttpRequest to access third-party domains via GET doesn't open any new security holes.

If you're already vulnerable to CSRF via GET, the existing "embed a script tag" (or even just "embed an image tag") will already work to exploit that weakness.

The lack of this ability, on the other hand, has caused people to create horrendous security vulnerabilities solely to work around an ineffective security measure.

And here is where a poorly thought out security model is compounded by people trying to do things that their tools were never designed to do. The result is a mess like you are describing.

Fortunately, this can easily be resolved in browsers that fully support HTML5 by using cross-site XHR, but it does require that the websites explicitly reply with response headers that indicate cross-site requests are allowed. Good reason to file feature requests on sites like FaceBook, Google Maps, etc. asking them to support this feature.