JavaScript and Ajax Security Overview
by Jeremy Conley
Posted in Articles, Coders, PHP on
Overview:
Asynchronous JavaScript and XML, or Ajax as it is much better known, was a major milestone in web development. Previously, a web browser would have to make a completely new request to the server to update the page’s data. This meant that web “applications” were slow and clunky. A user would have to wait for a complete page to load to see if any of the data, such as their inbox, had changed. Ajax changed all of this by allowing JavaScript to make requests to the server directly then update the page without a full reload. This saved time since an Ajax request could download just the changed data without needing to download the full HTML source, images, etc. on the full page. In addition, Ajax is what makes a web application act like a real local computer based application. The user has a faster, more responsive, more interactive experience all within their browser. Google’s Gmail Internet application was the pioneer in this area, and this method has been utilized on countless websites since then.
While Ajax is a relatively new technology, the principles it is built on are the same ones we already know. For example, while an Ajax request may or may not be triggered by a user’s action, it is still just a standard HTTP request, and the response is just a standard HTTP response. However, what makes Ajax potentially dangerous is that it nicely hides these HTTP requests and other in-page interactions. Ajax is completely reliant upon JavaScript coding to work: there is no browser UI at all for end users to create Ajax requests like a regular request (i.e. the browser’s address bar). Ajax by itself is not dangerous, but it does present a serious potential problem since an application’s complexity increases (more possible attack vectors) and a developer might be tempted to skip checks since so much code is needed.
Defenses:
As we have already seen, Ajax is just a new way of playing with existing protocols and technologies like HTTP requests or the browser’s Document Object Model (DOM). The same basic security principle of always filtering input and escaping output applies here as well. A typical Ajax request will take an event (such as clicking on an email’s subject) and then sending a request to the server to load the email’s content. Although this request cannot be modified by the user directly as the browser’s address bar is not changed, it can still be modified by using browser tools such as Firefox’s Tamper Data extension or a tool such as Web Scarab. A developer should not spent too much time with client side validation since any of it can be modified by attackers. This is not to say that client side validation is not needed. It is for a better user experience so the user will instantly know if she or he (accidentally) submits invalid data. However, the developer should be very careful that the server filters the input before accessing the database or email server since client-side validation can be bypassed.
Similarly, a developer should decide whether or not an application should be able to receive HTML from the server via an Ajax request. If not, the application should escape the data before displaying it in the browser to the user. Unfortunately, JavaScript has no built-in equivalent of PHP’s htmlentities() function. However, there is a workaround!
<script>
function escape(text)
{
var div = document.createElement('div');
var text = document.createTextNode(text);
div.appendChild(text);
return div.innerHTML;
}
</script>
The method is to take the input, create a div element in memory, assign the input to the div’s displayed text, and then copy that displayed text back. This forces any HTML into safe equivalents since the div’s inner text property can only store plain text.
If an application must use HTML to show results back to the user, a safer method would be to get the raw data via Ajax then use the createElement() JavaScript function to manually create the necessary HTML elements then assign their content to the data from the Ajax request. While this is a lot of additional work for the developer, it is safer since it will prevent XSS attacks since all data shown in the browser is known to be safe.
This is a better approach since it assumes all data is possibly malicious. It bears repeating that all input should be considered suspicious. Even if the Ajax request is pulling data from the developer’s own server, their is no guarantee that the data has not been tampered with in transit or that a hacker has not injected malicious content in the stored data on the server.
Working with plain text or HTML is problematic enough. A developer should never use Ajax provided JavaScript in their own application. XSS attacks through HTML are dangerous, but using non-trusted JavaScript could lead to malware installation or other worse attacks. Using JavaScript’s eval() function on external JavaScript is just asking for trouble.
Conclusion:
Ajax is a wonderful JavaScript enhancement. Used correctly in the hands of a skilled developer, it allows for a much more desktop like environment within a web browser. Ajax has truly helped introduce a whole new breed of web applications such as Gmail, Google Maps, Google Suggest, Google Docs, and more that bring the user interface of a desktop app with the convenience and availability of the web. However, if a developer does not recognize some of Ajax’s potential security problems, then both the user’s browser and the server could be compromised.
about the author
More about Jeremy Conley:
Jeremy is a student at Western Michigan University where he is dual majoring in Electronic Business Design and Film & Video Studies. When not programming or researching design and security topics, Jeremy enjoys movies and photography and drinking coffee in all the amazing local Kalamazoo coffee shops.
questions or comments?
If you have any questions or comments about this article, feel free to contact us!