Introduction to Cross-Domain Ajax
What’s this all about?
First, lets talk about the problem for a bit. It goes by the name same origin policy, and this explanation from mozilla.org is typical:
- The same origin policy prevents document or script loaded from one origin from getting or setting properties of a document from a different origin.
- – From http://www.mozilla.org/projects/security/components/same-origin.html
This means that it is largely impossible to load scripts from one domain into another. For example, the following are prohibited:
- Issuing an XMLHttpRequest() to another domain (a core component of Ajax).
- Accessing or modifying the DOM of a <frame> or <iframe> which has a src attribute with another domain.
- Accessing or modifying another window (or tab) which has a different location.
So what’s the problem?
The same-origin policy exists to prevent malicious use of resources. If there were no rules governing cross-domain script access, it would be trivial to wreak all manner of havoc on unsuspecting users. It would be easy, for example, for a malicious website to grab your session information to another site and execute actions on your behalf.
For one example, consider this:
- You go to your favorite webmail program – it could be Gmail, Yahoo mail, Hotmail, or a private internal company webmail program.
- After signing in and checking your email, you click a link to a malicious site which opens in a new tab.
- The malicious site checks the http referer and sees that you came from your email account.
- Using cross-domain scripting, the malicious site reaches back across into your email tab and downloads your address book and all your emails (or however many it can get before you close the popup).
- Subsequently, after scanning your emails for passwords, financial data and other sensitive materials, it sends all your contacts an email from you endorsing the same site.
And that’s just one example. A more insidious plot would involve a malicious third party using your browser to spider your company’s intranet, leaking classified information with you as the unwitting accomplice!
Then the same origin policy is a Good Thing, right?
Well, yes and no. The same origin policy is good at keeping scenarios like the aforementioned from occurring, but it’s not the only way, and it has some significant drawbacks. For example, consider Yahoo!’s variety of web services. The Yahoo! Developer Networksite openly advocates using their services in building web applications. However, without the proper setup, an unknowing web developer is destined to run face first into the same-origin policy.
Clearly the developer’s server isn’t in the yahooapis.com subdomain where data will be queried from, so how can Ajax requests be issued to their web servers?
Proxy, proxy, proxy
To Yahoo!’s credit, they’re at-the-ready to explain how to use a web proxy for cross-domain XMLHttpRequest calls. Incidentally, this procedure of using your own web server as an intermediary to third-party web services is often the first one new developers will find, and it’s also potentially the most costly.
As Joe Walker from Getahead explains:
- Why Do People Want Cross-Domain XHR?
- Because it makes SOA happen in a way that it can’t now. Currently if I think of a great mash-up, I will need a fancy server to make it happen, I have a lot of unnecessary extra coding, and when I get Digged or Slashdotted, I’m dead. With Cross-Domain XHR, all I need is Ajax and I’m all set. No server side computation required, no server side coding, no needing to make calls out of your server, life is a lot simpler and you have a much greater chance of surviving becoming famous.
- – From http://getahead.org/dwr/ajax/cross-domain-xhr
Due to the server requirement, this is not always a desirable option. Plus, if you’re going to invest in the requisite infrastructure to set up a scalable, performant web-proxy, then you’ll probably end up implementing some server-side caching to cut down on total bandwidth. And at that point, you’re really providing enough of a service that adding your own value-added features (data aggregation for example) makes sense. Scope creep anyone?
Another problem is the same-IP funnel. If the remote site isn’t actively supporting third-party development against their public APIs, they may simply block your server’s IP from incoming requests when it becomes a noticeable fraction of their total traffic. Changing your server’s IP address may be costly, difficult, or even impossible in some circumstances.
What else is there?
About the only other way to do cross-site scripting effectively is by way of On-Demand Javascript. In this very simple technique, you inject new <script> elements into your web-app’s DOM, with dynamically created src attributes. This behaves much like an XMLHttpRequest() using the GET method, but without any domain restrictions.
The one caveat however is that the third-party’s service has to output valid JavaScript. Ideally, that third party supports some kind ofJSONP reply structure, but sometimes you can get by with just JSON IF the object is wrapped in an Array. By overloading the Array class constructor you can actually “execute” the data, but this is rather hacky and easily defeated.
Gmail was susceptible to this kind of cross-domain scripting, but closed the hole over a year ago, shortly after it was discovered. Jeremiah Grossman has an excellent writeup of these advanced web attack techniques using Gmail.
In any case, to use On-Demand Javascript, the third party has to provide valid JavaScript as the Ajax response. There are notable instances of this in the wild, for example Google Suggest returns JavaScript in its Ajax responses, which it executes via an eval()call*. However, this is in the vast minority of cases.
- * Please see my previous web hack What Would Google Suggest? for more details.
Conclusions
Clearly the state of cross-domain scripting is not to the advantage of the aspiring web developer. Although the cross-domain policy in place today keeps bad things from happening, it is much too restrictive to promote (or even allow) the next-generation of web-applications to be developed.
Over the course of the next few weekly web hacks, I’ll go over some lesser known and never-before-seen solutions to enabling cross-domain Ajax. Stay tuned!
Hope this helps. As always, I’ll be happy to answer any questions.

0 Comments.