home

Softsteel Solutions

About Us Contact Us Newsletter Training
Tutorials
 

ASP.NET Ajax Tutorial Lesson 11: Security

printer friendly version

Most of the ASP.NET Ajax security issues are covered by standard ASP.NET and Web Service security issues. For instance, calls back to the server for Partial Page Updates run through the page lifecycle, and thus are covered by all of the security covering the page.

There is, however, an issue that arises because of the use of JSON to pass sensitive data from the server to the browser. The threat is known as ‘Javascript Hijacking’.

To describe the problem it’s helpful to start with cross-frame security. So, suppose that we go to site BadServer, and it returns us a frameset page with frames delivered from both BadServer and a remote site GoodServer :

a representation of a frameset page with two pages, one from a 'good' server and one from a 'bad' server

Now, because it’s bad, the page from badServer would quite like its javascript to have access to the page from goodServer. It might be able to pick up interesting, sensitive information from the page, or pick up the values of session cookies, which it could then send off to bad people to use for their own bad purposes. In order to stop this, there is a ‘cross-frame security restriction’ in modern browsers which says that pages can only access each other if they derive from the same domain. Since badServer and goodServer are different domains, these pages are kept separate.

Now, the XmlHttpRequest object would seem to offer badServer a way around this security restriction. This object is manipulated by script, and its purpose is to make requests to servers, passing along all of the relevant authentication and other cookies, and grab the results. So why couldn’t the code served up by badServer just include an xmlHttpRequest object that pulled the HTML from goodServer?

a representation of a page from a 'bad' server pulling the HTML of a page from a 'good' server via an XmlHTTPRequest object

In order to stop this happening, the XmlHttpRequest object by default cannot make calls across domains. This tends to annoy people who like the idea of ‘mashups’ - pages which try to pull bits from lots of different servers - but as we can see there is a good reason for the restriction.

Now, there are various HTML objects which can bring in data from different domains. Remotely hosted images, for instance, can generally be included into one’s page. And as it happens, one of the objects that can work cross-domain is <SCRIPT> tags, allowing you to include javascript from other sites into your page.

Generally this isn’t any kind of security problem, because everyone knows that client-side script files are easily downloadable and so they don’t tend to include secrets. But it becomes a problem when Ajax-enabled sites start passing around data in the JSON format. The trouble is that the JSON format is well-formed javascript, so when it is requested by a <SCRIPT> tag it will parse and execute in the context of the page. It is then available (through some tricks involving overriding the default constructors for objects and arrays) to the script in that page.

Here’s an example of the problem (based on the real life attack on GMail). Suppose that you have a cool Ajax web-based email application, and part of the site’s functionality is to request your list of contacts from the server. That is, suppose that there is a URL like this:

http://goodServer/webService?getContacts

which returns (for the calling user, which is known by the session cookie) a piece of code like this:

{"c1":"fred@secret.com ","c2":"bill@hidden.co.uk "}

Now, if a bad page served up by badServer contains the following Script element:

<SCRIPT type=”text/javascript” src=” http://goodServer/webService?getContacts” />

Then this piece of code will execute and will be accessible by the script on badServer. This is the essence of the ‘Javascript Hijacking’ attack.

So, is ASP.NET Ajax susceptible to this attack? Not by default, but it is possible to fall into this trap.

The countermeasure that ASP.NET Ajax takes against javascript hijacking, is to require that Ajax calls to web services contain a content-type header ‘application/json’. If the calls don’t contain this header, then no useful information will be returned. Now, the XmlHttpRequest object is able to manipulate the content-type header in this way, but the script tag isn’t. So the script statement above would not return the JSON. This is all laid out in the following blog entry: http://weblogs.asp.net/scottgu/archive/2007/04/04/json-hijacking-and-how-asp-net-ajax-1-0-mitigates-these-attacks.aspx.

However, Brian Chess of Fortify Software has pointed out that there is at least one way around this countermeasure. Versions of Flash earlier than 7 allow one to manipulate the content header for requests. And while they these versions of Flash do enforce a cross-site request restriction, there is a flaw in that they allow the responses to get stored in the browser cache. Together these add up to the fact that if ASP.NET Ajax is set up to a) allow GET requests and b) allow script caching, it is possible for an attacker to pick up the JSON response. This flaw is made more important by the fact that some have suggested allowing cached GET requests as a way of improving efficiency.

For now, then, if there are security concerns about the data being passed via JSON, then one should not turn on the combination of features described above.

 

ASP.NET Ajax Tutorial