Ajax Security Issues
This article is about exploring major security issues we come across during assessment of Ajax based applications.
AJAX:
Ajax or 'Asynchronous JavaScript and XML' is a relatively new and dynamic technology on the web, which works in asynchronous way to interact with the server. In a traditional web approach for making a new request the browser had to refresh entire page and reload it, which was both time consuming and bandwidth consuming. With AJAX, the subroutines can request the server for new piece of data without entirely reloading the page, thus giving users a faster and enriching experience. It happens in the background without user's knowledge and what the user sees is a smooth experience. The XMLhttpRequest object is used to do the interaction with the server. One simple example of the Ajax request is the population of suggestive words by Google Search, while we start typing the words. Without sending the entire content, it keeps guessing, updating and loading the search results without hitting Search button.
The data in an Ajax request/response can be in the form of XML or JSON, which is considered a light weight data to transport compared to the traditional form based data.
Data leakage in Ajax or JSON Hijacking:
Before moving on lets understand an important concept:
1. JavaScript expression
2. JavaScript Array
JavaScript expressions are not executed by JavaScript parser, but arrays are:
for ex:
[javascript]
<script>
{"t":1,"p":1,"r":1,"rows":[{"i":0,"c":["n","H, C","A","5","T","n"]}]}
</script>
This will not be executed, that is, objects won't be created. The above example is for a JavaScript expression.
But now when it is converted into a array as given below:
[javascript]
<script>
[{"t":1,"p":1,"r":1,"rows":[{"i":0,"c":["n","H, C","A","5","T","n"]}]}]
</script>
This gets executed.
The scenario:
-
The user logs into a vulnerable application (victimsite.com) which server is JSON in form of Array and data are sensitive in nature. The user gets the authentication token (AUTH) by the application.
-
The attacker lures the logged in user to click on a link, using Phishing or sending an email to the user.
-
The user clicks on the link, which loads the page from the attacker's website, which embeds the following script:
[javascript]
<script>
Object.prototype.__defineSetter__("t",function(obj){alert(1);for(var i in obj) {alert(i + '=' + obj[i]);} });
</script>
<script>
src="http://victimsite.com/mainJSON"/> //this points to the JSON
</script>
[/javascript]The script again makes a request to victimsite.com and access the main JSON page which sends the sensitive data back to the attacker's page, which have now both: the JSON data and the AUTH token.
However, the prerequisites for the above attack are that the JSON data must be sensitive in nature and the browser should accept __defineSetter__ method, which overrides the existing DOM or functions when a property setter is called. In above example, whenever an property 't' is being called, a function alerts it and displays it. However not many browsers support 'defineSetter' method now.
Countermeasures:
-
Never send sensitive information in JSON or don't send them using JSON array, which makes it a valid JavaScript that can be accessed via script tag.
-
Serve the authenticated request only, means use some sort of authentication to protect the data
-
The JSON data must be sent over POST, not GET, which would make it difficult to include the URL in <script> tag
What is CSRF?
CSRF stands for Cross Site Request Forgery, exploits a basic flaw in web technology, which relies on cookie based authentication and submits it with every request from user to the server. With CSRF an attacker can trick a user to perform, which is an action that was not intended. The user at the time of the attack must be authenticated and have a valid session ID. The attacker is also a valid use of the application and knows the internal functioning of the application. More on CSRF here:
CSRF and Ajax:
Although the CSRF is pretty much prevalent in traditional web applications, if prevention is not implemented, it also can be carried out on Ajax based web apps. The only difficulty is, since it's a hidden request, it's not that straight forward to create a valid request. We need to craft not only the compliant request but also we need to stick to the valid data format.
Steps of attack:
-
The user is authenticated to the web application and browsing its contents.
-
The attacker, who also happens to be a valid user, creates a script and tricks the authenticated user to click on a link which fetches the following html page and loads in his browser.
-
Thus the browser makes the request on behalf of the authenticated user.
Picture 1
Countermeasures:
To prevent this attack, similar to the traditional approach, there are two ways for this to happen:
-
Embedding non guessable, random tokens called nonce in the requests/ responses to differentiate between authenticated user's requests and one coming from attacker. This approach basically server embeds nonce in the requested page. When the user, submits the page the server checks the availability of the nonce, and matches it with sent one, if matched, request is fulfilled, otherwise rejected.
-
Using Anti-CSRF header: The idea is to generate a custom header, x-session-token in this case, with every request which is considered sensitive and includes any sort of transaction. For example: xhr.setRequestHeader('x-session-token', csrf_token)
At the server level, server checks for this header if found request is fulfilled, otherwise rejected. We need to use xhr calls for making use of this technique, not useful in regular POST and GET requests.
XSS and Ajax:
XSS or Cross Site Scripting: When an application doesn't sanitize the user input or output before rendering into the html, it becomes a luring target for the attackers as they can insert malicious JavaScript into the application and subsequently carry put a rage of attacks, such as, session hijacking, phishing, malware infection etc. More here:
Looking for XSS in Ajax applications:
Possible pointers for XSS are the presence of following functions in JavaScript files (.js). The Ajax receives the response from backend and populates the browser using one of the following functions:
document.write(): This may potentially lead to dom-based XSS, if the values are not being properly sanitized or modifying a specific part of the information using eval() is another pointer.
Other vulnerable functions are identified as innerHTML() and write().
Carefully scanning the JavaScript files which loads at the client side at the time of target page loads can give some clues about the possible vulnerable functions being used. One tool which is great and very handy in doing such analysis is FireBug. We can identify all the Ajax calls under XHR tab (Fig):
Scanning the JavaScript files is also very easy with this tool. It will list down all the dependent .js files, which in turn can be reviewed for presence of one or more above mentioned functions. Clicking on Script tab provides all the JavaScript files loaded:
Additionally look for the following instances:
[javascript]
if(window.XMLHttpRequest)
http = new XMLHttpRequest();
eval(info);
if(window.XMLHttpRequest)
http = new XMLHttpRequest();
document.write(blogdetail);
We need to analyze these functions as they may be entry point for un-sanitized streams, which can be exploited.
A nice example from iSec Partners:
XSS payload in Jason and their effects:
[javascript]
var inboundJSON = {"people": [
{"name": "Joel", "address": “<script type="text/javascript">// <![CDATA[
badStuff();
// ]]></script>", "phone": “911"}]};
someObject.innerHTML(inboundJSON.people[0].address); // Vulnerable
document.write(inboundJSON.people[0].address); // Vulnerable
someObject.innerText(inboundJSON.people[0].address // Not Vulnerable
Countermeasures:
Pretty much the same as we would do for conventional XSS prevention:
-
Input validation: Strict check on what's allowed and what's not in the user input. Properly sanitizing and whitelisting of allowed characters.
-
Output validation: That means, all the output must be properly encoded before presenting to the user such as HTMLEncoding.
Conclusion:
So, most of the issues affecting Ajax are those of traditional web applications and they might be mitigated same way.