W3C home > Mailing lists > Public > public-webapps@w3.org > April to June 2009

Re: [cors] security issue with XMLHttpRequest API compatibility

From: Tyler Close <tyler.close@gmail.com>
Date: Mon, 6 Apr 2009 14:23:38 -0700
Message-ID: <5691356f0904061423v198f4f0do3eab7f8a20e77904@mail.gmail.com>
To: Jonas Sicking <jonas@sicking.cc>
Cc: public-webapps@w3.org
On Mon, Apr 6, 2009 at 1:54 PM, Jonas Sicking <jonas@sicking.cc> wrote:
> On Mon, Apr 6, 2009 at 11:29 AM, Tyler Close <tyler.close@gmail.com> wrote:
>> It looks like the client-side API for cross-origin messaging is the
>> same as the current XMLHttpRequest API. I think there's a security
>> issue with this decision. The current XMLHttpRequest implementation
>> drops any attempted cross-origin request. This implementation protects
>> a client-side application that inadvertently sends a request to an
>> unexpected target URL. Since the request is dropped by the browser
>> implementation, any client credentials (such as a password) in the
>> request body are not exposed to the wrong server. Since XMLHttpRequest
>> has, to date, provided this protection, client scripts have had no
>> real need to vet the URLs that they send messages to. Consequently, it
>> seems unlikely that these scripts do any vetting of their target URLs.
>> It may be possible for an attacker to cause a client script in another
>> domain to send a request to a target URL on the attacker's server.
>> Since the attacker controls his server, the resource can be marked as
>> accepting cross-domain requests. Since the client script wasn't
>> expecting such requests to succeed, it may include client credentials
>> in the sent request.
>
> How would the script include client credentials in the request? Can
> you show some an example of the type of script you are concerned
> about?

Using a variation on the example in the spec...

var password = ...   // global variable holds user's password

function deleteItem(itemURL, updateUI) {
  var client = new XMLHttpRequest()
  client.open("DELETE", itemURL)
  client.onload = updateUI
  client.onerror = updateUI
  client.onabort = updateUI
  client.send("password=" + password)
}

So now we have to wonder where the value for the itemURL parameter
comes from. Perhaps it comes from an HTML element in the current
document, and has a value that was determined by the attacker in some
previous interaction. For example, perhaps this is code from a shared
blogging site. The function is deleting items from an Atom collection
and the itemURL came from a feed representation. If the author of that
feed is the attacker, he might be able to use an item URL that refers
to a resource on his own server, rather than on the shared blogging
site. Before [cors], this attack would not have worked, since the
browser would have dropped the request on the floor. Now the request
goes through.

--Tyler
Received on Monday, 6 April 2009 21:24:18 GMT

This archive was generated by hypermail 2.3.1 : Tuesday, 26 March 2013 18:49:31 GMT