Feb 2, 2008

Using Google Gears to detect XSS

As cross-site scripting can be exploited in many ways, I've experienced in my past the need to place an HTTP resource on a remote host and reference it from the web application under test. When such resource is used for capturing data from the web application under test, one must have access to the remote host's HTTP logs. What if that's not possible?

One of the first things that I looked at in Google Gears was its ability to cache HTTP resources (except for streaming resources, but that's a whole different story). As a resource is cached, Gears records the last time this resource has been updated from the Internet. However, the part interested me more was in obtaining the last time when the browser attempted to display this resource. Unfortunately, Gears does not provide APIs; therefore a work around must be used.


To address my need of knowing that my captured data has gone to my intended resource, I've taken the concept of using different images for 1) the resource itself, 2) failed attempt to capture data, and 3) successful attempt to capture data. The following manifest represents the role of each image:
{
"betaManifestVersion": 1,
"version": "v0.1",
"entries": [
{ "url": "imageTest.html"},
{ "url": "green.png"},
{ "url": "green.png?capturedData=", "src": "blue.png"},
{ "url": "green.png", "ignoreQuery": true, "src": "red.png"}
]
}

Next, to ensure that all data is properly cached into Google Gears, the browser is navigated to a page that kicks off the process. Finally, once Gears and the browser is properly set, the attacker's web site simply goes "offline". Note that the browser's cache might interfere with this process; therefore it's a good idea to clear the browser's cache once the attacker's site has gone offline.

My current belief is that this approach (along with checking the resource's URL in the browser window) is a good mechanism for determining if a) a page is vulnerable to XSS and b) an attacker can steal data from that page. However, I'm yet to try it out on a project. :)


A working demo of this can be found here.

No comments: