Introduction to AJAX Security
As I start investigating the use of AJAX technology for new or existing Web Applications there are some major concern around Security that arises. The good news is—for the most part--securing AJAX enabled Web Applications is very similar to securing traditional Web Applications except there are a lot more moving parts. This, I hope, will be the first in a series of blogs on AJAX Security.
So what are some of the major security concerns around AJAX?
Lack of Best Practices
If you are building a traditional ASP.NET 2.0 there are numerous best practices on creating a Secure Web Application. However, as you start digging into developing an AJAX enabled Web Application you will not find a shortage of information. There are numerous articles, sample code and videos on AJAX. These samples are meant to demonstrate a specific feature or set of features available for the novice and thus these examples do not cover security. With AJAX still being a relatively new technology many developers will cut and paste sample code into their application. Without understanding potential security vulnerabilities of the sample code then the chances of creating security exploits are a real concern. As the saying goes “One person feature is another person exploit”. Just because there are samples code out there to demonstrate a feature you really have to decide if you want to use that feature and if so how do you secure it against potential threats it may bring to the application. For example, there some sample code that shows how to use the autocompletetextbox. In this scenario, as you start typing characters in the textbox, JavaScript is executing in the background and making a call to a Web Service that is retrieving information from a database to autocomplete the entry in the textbox. Very cool indeed, however, as an attacker all I need to do is to write a script, randomly generate some characters into the autocompletetextbox and loop through this about 1000 times. Boom! I just created a denial of service attack by bringing your database to it knees. The problem here is the sample never mentioned you should cache the results from the Web Service.
XMLHTTPRequest
The core of AJAX is the power of the XMLHTTPRequest object. This is what provides the client the ability to send JavaScript request to a Server and in return receive JavaScript responses that can be evaluated on the client. Furthermore, XMLHTTPRequest provides JavaScript with the ability to execute independent of the user. Therefore, JavaScript request can be launched on timer controls, keystroke etc. This will lead to more request to the server and each of these requests are AJAX endpoints.
If you are not using SSL for all of your pages then there is a lot more information being send across the wire in clear text. Thus, if a hacker was probing your AJAX Web Application then the end user would be able to discern function names, variables, parameters, return type, and data types. These additional endpoints increases the attack surface of an application. Furthermore, with AJAX it is possible to distribute a significant amount of the code on the client and not just the Server anymore. This allows the developer to embed more code on the client side including the ability to create richer client side controls. The power of the JavaScript can lead to Cross Site Scripting attacks that has the ability to prorogate like a worm. Let examine some of these security concerns in greater details.
Client Side Controls
The goal of AJAX is to build richer browser based application and one great way of doing so is by moving some of the server side controls to the client. Not only does this increase the attack surface on a insecure environment but some of these controls are being advertised as providing security. Case in point are the client side controls for input validations. There is no such thing as security on the client. Client side validation controls are meant to provide better performance and responsiveness when the honest end-user makes a mistake.
Providing the client with a richer interface or more functionality does not change the fact the client is still considered insecure. Once you release the application in production you have no control over the client or how it is being used or who is using it, thus it cannot belong to Security sub-system like your Servers do. You must always rely on doing validation on the Server before any input is passed into a trusted resource such as a database. All input must be considered evil until proven otherwise. Personally, I think the client side validation controls need to be accompanied with big red neon lights saying this will help with performance and not security.
- Client Side Validation!=Security
- Client Side Validation=Performance
If you are relying on client side validation then all the hacker has to do is disable JavaScript in the browser and a more sophisticated hacker will create their own client that mimic yours but without any of the validation.
JavaScript Web Service Proxies
AJAX for ASP.Net 2.0 provides the ability to generate JavaScript proxies which provides the client with the ability to use JavaScript to call Web Services. The initial design of many Web Services was to accommodate a B2B environment in which the authentication, authorization and input validation is done for the most part on the middle-tier systems. Now with the client calling the Web Services directly then this may by-pass the middle tier security layer. Furthermore, I have not seen anything in the client side proxy that use WS Security such as User Name or security tokens as you can be done with Server side proxies. Therefore, having a client calling the Web Service directly without totally verifying the security requirements of the application may provide hackers with an endpoint that has direct access to trusted resources. Furthermore, if this Web Service calls the database and no input validation is being done on the Server then you are opening yourself up to SQL Injection attacks.
Cross Site Scripting (XSS) Attacks
XSS is now on steroids as the attack can occur behind the scene without your knowledge. With the traditional Web Applications there was at least some kind of visual cues. With AJAX it is possible to send some value via an input parameter to the Server and the response from the Web Server can contain JavaScript snippet where the client can evaluate the code by using the eval() function.
It seems there are still a lot of developers are still using a deny listing technique of looking for dangerous characters such as script but what if the hacker does not use script but rather they use eval() or use something like the <img> tag with a source attribute equal to javascript:txt.
<img src="javascript:txt='function someattack()...'/>
This is just another example of canonical attack. Therefore, if you are going to prevent XSS attacks by looking for the word “script” then a hacker will have you in their sights with eval() or other ways of representing the same characters or function.
Even more dangerous is the ability for JavaScript to work independent of user thus making it possible for XSS to propagate itself like a worm. The prime example is what occurred to MySpace.com. I am not condoning what was done here but rather providing you with a link that provides a technical description of how Cross Site Scripting attacks has increased in severity. Actually, worse of all here is another example of using Deny or Black listing for input validation against unwanted characters. Every time we hear of attacks in which some form of input validation was circumvented it is always because of Black or Deny Listing. We have to start using White or Accepting Listing when making decision on what is considered to be acceptable characters. Always fail on the side of caution.
Increased Attack Surface
With AJAX there is a perceived performance increase by making more frequent but smaller requests back to the server independent of the user. Furthermore, AJAX is not just about the Server but it has equal focus on the client. Therefore, the application complexity and code base will now shift from the Server to the client. This will increase the attack surface on the client which is next to impossible to protect as it lies outside of any trusted subsystem.
It is easier to secure something you can see like the query string being passed in the URL. But what happens when you cannot see the URL and query string as is the case with AJAX since many of the request are occurring in the background. Unfortunately, developers may forget to protect the numerous additional end points.
Let me leave you with this thought:
"AJAX allows for JavaScript to be able to connect to the Web Server independent of the user. Extremely powerful for creating Web Applications. Since AJAX provides us with the power to make the client perform tasks that was once only available on the Server, then it is equally important to realize that a hacker can take advantage of this capability. More than ever it is critical to perform threat modeling to thoroughly understand all the end-points and all input being passed to the Server."