XML News from Thursday, February 21, 2008

The W3C Voice Browser, Web APIs, and Web Application Formats (WAF) Working Groups have posted a new draft of Access Control for Cross-site Requests (formerly "Enabling Read Access for Web Resources" and "Authorizing Read Access to XML Content Using the <?access-control?> Processing Instruction 1.0"). According to the draft,

Cross-site requests are possible using the HTML img and script elements for instance. However, it is not possible to exchange the contents of resources or manipulate resources "cross-domain". This is to prevent information leakage and to ensure that malicious site can not delete your calendar data with cross-site requests using the HTTP DELETE method.

The policy this document introduces allows a resource to opt-in to allowing cross-site data retrieval of it and also enables a mechanism based on the same policy to allow a resource to opt-in to requests using an HTTP method other than GET. This policy builds on top of the existing restrictions already in place. This policy described in this document can only be used by a technology, such as XMLHttpRequest or XBL, when the respective specification of that technology describes how it applies.

The access control policy is defined in the resource that might be obtained and is expected to be enforced by the client that retrieves and processes the resource. Thus the client is trusted and acts as a policy enforcement point.

If you have a simple text resource residing at http://example.com/hello which contains the string "Hello World!" and you would like the hello-world.invalid domain to be able to access it the resource would look as follows (including one HTTP header that is significant):

Access-Control: allow <hello-world.invalid>

Hello World!

The hello-world.invalid can now access this document using XMLHttpRequest for instance with the following code:

new client = new XMLHttpRequest();
client.open("GET", "http://example.com.com/hello")
client.onreadystatechange = function() { /* do something */ }
client.send()

I've had this one explained to me repeatedly, and I still don't understand exactly what's going on here or why it isn't a security hole, but I guess there's a use case for it.