It's August, the sun is sinking on a beautiful sunny day in the heart of London and everyone who can has packed into the capital's beer-gardens.

One of the most popular pubs at this time of year is The Server Inn on the river Webb. Owned by a wealthy American named Bezos, it's become the spot to be seen since getting a license to serve drink on the adjacent riverbank.

Jeff was so proud of this new feature he trademarked it under the name Webb-Service and even drafted in some foxy waitresses to deliver it.

Webb-Service proved to be one of the smartest moves Bezos made with and without fail, summer nights see the river bank packed out with punters enjoying a pint in the evening warmth.

Regulations

Local government being local government, licensing Webb-Service was a tricky process.

During the final hearing, it was suggested that too healthy a combination of heat and Hoegaarden could easily lead to trouble.

Bezos was the first to agree that drunken punters toppling into the river and getting lairy in the Server wouldn't be in anyone's interests.

After a brief discussion, someone suggested that perhaps the barmen should keep an eye on whether drinks were going outside or staying in the pub. If they noticed any particular table ordering more than seemed sensible, they could always stop serving them and ask them to move on.

Bezos agreed that the idea made sense. Just as the license was about to be granted though, one of the other councilors piped up, "How will they know though? How will the barmen know whether a drink's for inside or outside the pub?".

"Easy", replied Bezos, "the server only does table service and our foxy, fiery waitress can just tell the people behind the bar which drinks are for Webb-Service and which are local".

An unexpected twist

"No, that's not going to be good enough" replied the council. "We're going to need a formal procedure for this Webb-Service. Hows about if outside orders were only allowed to be taken in German?"

Bezos: "Sorry?"

Councilor: "Take Webb-Service orders in German and internal orders in English, that way you'll know for sure where they came from. Only hand drinks over to users, ahem, customers, ordering in German."

Bezos: "You're kidding right? We could just have the waitresses tell the servers that an order is for Webb-Service?"

Councilor: "What if they forget to say so?"

Bezos: "What if they don't bother speaking German?!"

Councilor: "I'm afraid you're over-ruled Mr Bezos. The stipulation will be that all drinks ordered through your Webb-service must be ordered in German. The waitresses must fetch all orders, deliver them to the customer but only hand them over if the customer can repeat the original order. In German."

Bezos: "This is insane. I'm going to have to get all my customers, my foxy waitresses and my serving boys to learn German just for the sake of delivering Webb-Service? What happens if they deliver the drinks and the customers can't speak German?"

Councilor: "In that case Mr Bezos, you'll simply have to throw the drinks away. Orders from within the bar can be made in English but all orders from the river must come in German. Case closed."

Bezos: "Good grief. You're all insane."

Concilor: "We're not insane, Mr Bezos. We're government."

German (JSON)

We coders laugh in the face of such fumbling bureaucracy.

Clearly the onus for informing the servers lies with the waitresses. Whether they make the order in German is neither here nor there, all that matters is that they tell the server whether it was a Webb-Service order or internal.

The proposed system doesn't actually even inform the servers at all, it requests drinks whether or not someone's on the river bank and simply tips them away if they're not authorised to receive them.

We developers would clearly never implement such a foolish system... would we?

XMLHttpRequest and <script />

Unfortunately, it seems we would and we have. Welcome to the world of XMLHttpRequest (XHR).

As anyone who's worked with XHR knows, it can only be used to fetch data from the host site. All external requests are denied by the browser.

We can still get data from other servers but only by using a <script /> tag to pull in raw JSON.

The dangers of JSON

Where XML is commonplace with powerful tools implemented in most programming languages, JSON support is sparse at best. Not only that but JSON is far more than just data.

JSON is pure code executed in the scope of the script that receives it. This might be acceptable for trusted same-domain JSON but is extremely dangerous when we can't be certain of the objectives of the script author. By executing their script, we give them full access to our users' web-pages and data.

Cross-domain scripts could prove to become one of the biggest security holes of Web 2.0.

Google and Yahoo might currently represent trusted companies but every time you place a Google Map, a Flickr slideshow or Google Analytics into your webpage, you give those companies full access to every piece of data within that document.

That data includes but is not limited to cookies, DOM code and any passwords or information people enter into the page's forms.

The current state of play

  • We can request scripts data or images from any domain (XHR or iframe)
  • Data from our own domain can be delivered in either raw executable JSON or the inert XML format
  • Data from other domains can only be read if it's delivered in JSON

Why arbitrary cross-domain XHR is bad

Just as in Bezos' beer garden, it's important that the servers know whether a request is coming from. If I was able to send and read requests from arbitrary servers then I could easily use visitors to my websites for a brute-force attack on another site's passwords.

I put a little piece of code in a webpage that sends ten password attempts to Paypal and returns the results to my server. A few hundred thousand visitors later and I'll have myself a useable password or two.

I could of course level the same attack from my own server but thousands of password attempts coming from a single IP address are easy to spot and block. Thousands or even millions coming from different IP addresses are far harder to distinguish from legitimate requests.

Arbitrary cross-domain XHR makes any and every visitor to a website a potential zombie machine and is very definitely a bad thing.

What's the alternative?

So the problem is that we would like to be able to request data cross-domain but we need to make it clear to the server that this is the case.

Why not force the server to acknowledge that a request can be used cross domain? Flash uses a domain policy document on the server to achieve this but why not simply use the HTTP headers?

The entire cross-domain restriction is policed not by servers but by user-agents - browsers. Why not enable cross-domain XHR in browsers but only as long as the server actively agrees.

Authorising cross-domain requests using headers

If the server is happy to return cross-domain requests then it prepends them with:

Cross-domain-access: true

The browser only makes the data available to the XHR call if this authorisation header is present.

In this way, the system remains server opt-in but without the cumbersome requirement that opting-in requires all transactions to be processed in JSON.

Policing the system

My first reaction on reading the above proposal would be to object that it's client-policed and can therefore be over-ridden but then so is the current solution.

Cross domain XHR is limited only by the browser, not by the server and even then it's allowed when we use the script tag workaround.

Conclusion

Clientside cross-domain data requests are an extremely useful tool. They can only currently be done (in Javascript) using the script-tag workaround to deliver data as JSON.

Any cross domain XHR must be server opt-in (rather than opt-out) or else we leave all non-enabled servers vulnerable to brute-force attacks. Such an opt-in arrangement can very simply be communicated by having the server send a header authorising cross-domain use of the data.

External JSON is potentially very dangerous as it is arbitrary third-party code executed in the scope of the current web-page. It can be used to steal passwords or data present in the current scope. Not only that but JSON is not easily human-readable and is only an emerging data standard requiring server-side libraries that still aren't present or mature in most languages.

XML is already a data standard in wide use with API's present in most programming languages. It's inert, human-readable and highly compressible using gzip. It doesn't have the same execution convenience as JSON in a ECMAScript environment but doesn't need to be executed in an ECMAScript environment.

I don't know whether I'm missing a trick here but since the last 10 years have seen the development of a powerful language with a huge number of tools, meant specifically for packaging and accessing data, does it really make sense to bear off on a tangent with an entirely new format?

Any thoughts?