Web Security : Attacking AJAX - Checking for Cross-Domain Access, Reading Private Data via JSON Hijacking

9/25/2012 1:44:47 AM

1. Disrupting Client State

1.1. Problem

An application shouldn’t count on the validity of client-side data. With JavaScript and AJAX, an application should never depend on the accuracy of the client-side logic or state. This recipe discusses how to disrupt the client state, in the hopes that such information will be passed back to the server with adverse consequences.

1.2. Solution

From within this JavaScript, identify the item that you’re interested in. If it’s hidden, serialized, or obscured, you may have to trace out the JavaScript line by line. You can copy and paste the JavaScript file into the editor of your choice. In the case where the entire script is obfscucated, some editors allow you to auto-indent and format. This helps considerably with comprehension.

Once you’ve identified the variable, method, or object you’re interested in disrupting, move over to the Console tab in Firebug. From here, you can enter a line or multiple lines of custom Javascript to run within your current browser Javascript sandbox. For example, if your task is as simple as setting a new high-score value, you may write HighScore=1000 and then click the page’s Submit High Scores button and be done with it. If you’re going for something more complex, such as overriding the default behavior of an object so that it will pull an account with a different account number on the next AJAX callback, you’ll need to craft your own custom JavaScript.

1.3. Discussion

Because all web data must eventually travel via HTTP requests, there is nothing you can do via this recipe that you cannot also do by tampering with a request. The advantage this recipe offers is that it allows you to hijack the application itself, so that the application will set the parameters in accordance to a specific change in state. This saves you a lot of time, compared to the alternatives: computing all the HTTP parameters manually, just attempting generic attacks, trying to guess malicious values, or assigning values randomly.

The best example of this recipe is JavaScript-based games. Many JavaScript-based games will have a furiously complicated internal state. Furthermore, when reporting the game results to the server, it is not easy to tell which values correspond to the score, the number of tries left, or other details. Yet they’ll communicate back to the server for key details: updating score, downloading new levels, or changing the difficulty. If you’re going to cheat, say to get the highest high score (which would be stored server-side), it’s easier to modify the game than to intercept the communication. Changing the current_score JavaScript variable might be easier than deserializing a very long HTTP parameter, tweaking one part, and reserializing it.

2. Checking for Cross-Domain Access

2.1. Problem

When your application runs JavaScript from another site there is a risk that the other site could change their script to include malicious elements. Make sure your application doesn’t rely on untrusted external scripts.

2.2. Solution

Right-click on a page and select View Page Source. Search the source for the tag <script> specifically where the source ("src") attribute is set. If the source is set to a page outside of a domain you control, then the application relies upon cross-domain JavaScript.

Or, test this programmatically. In a Unix prompt or Cygwin, download one or more pages to scan into a folder. Navigate to this folder in in a command shell, Cygwin, or a command-line terminal. Example 1 will identify every instance in your set of pages where a script refers to an external source.

Example 1. Search multiple files for external script references
use HTML::TreeBuilder;
use URI;

#Specify valid hosts and domains here. The script will skip these. 
my @domains = ( "",
                "" );

#Parse each file passed via the command line:
foreach my $file_name (@ARGV) {
    my $tree = HTML::TreeBuilder->new;    
    #Find each instance of the "script" tag
    @elements = $tree->find("script");
    foreach my $element (@elements) {
        #Get the SRC attribute
        my $src  = $element->attr("src");   
        if( $src ) {
            $url  = URI->new($src);
            $host = $url->host;
            #Skip the specified domains
            if(!(grep( /$host/i, @domains ))) {
                #From the SRC URL, print just the Host
                print $host;
    #Delete the tree to start over for the next file
    $tree = $tree->delete;


2.3. Discussion

There are times when running untrusted JavaScript is not only permissible, but necessary for your website to operate correctly. Mashups, sites that blend functionality from multiple sources, will need to load JavaScript from their sources. For example, you can embed a Google map or YouTube video without running external code. If such functionality is crucial to your website, then this recipe is largely moot. On the other hand, very few sites require functionality from other sites—usually they’re incorporating data or an entire page. If you can, grab the data you need via a gateway on your application server, then deliver it within the same page as your other content. This allows your application to filter out just the data it needs and thus reduces the trust placed in a website you can’t control.

When deciding whether or not to include external scripts, ask yourself: would you grant this third party access to your source code revision control respository? To your user’s data? Including such a script on your website gives them implicit permission to execute JavaScript code within your domain. This lets the third party edit the appearance and functionality of your application, as well as access to your user’s cookies.

3. Reading Private Data via JSON Hijacking

3.1. Problem

Every URL used for an AJAX request can also be accessed directly from a web browser or from within another page. This means cross-site reference forging (CSRF) attacks,  can be applied to AJAX requests as well. Beyond this, there’s a new attack out known as AJAX hijacking, or more specifically, JSON hijacking. This new attack allows one to read private data via a CSRF-like attack, rather than initiate an action à la CSRF. So far it applies only to JSON serialized data—if your application does not use JSON, it is safe. We’ll walk you through testing for JSON hijacking in this recipe.

3.2. Solution

If your application returns JSON data at a particular URL, first log into your application, then try browsing directly to that URL. If no data is returned, then it’s likely your application already checks for a token or secret parameter beyond the HTTP cookies. If it does return data, check the JSON response data to see if your server includes any specific protection against JSON hijacking. If your application returns confidential, but unprotected JSON data upon request, you should flag it as vulnerable to JSON hijacking.

For example, an AJAX application may send a request to If this page immediately responds with JSON, such as {"user": { "fname": "Paula", "lname":"Brilliant", "SSN": "078-05-1120" }, "accountNumber": "3157304449" }, then it’s likely this application is vulnerable to JSON hijacking. An attacker could inject JavaScript to submit requests for many identifiers, gathering information on each account.

3.3. Discussion

Note that this recipe applies in two situations. First and foremost, if your application displays this data without any authentication, you can be sure it can be read by a malicious attacker just by navigating to the page. The case where such protection will help is if the data is also available to a logged-in user and an attacker executes a CSRF-like attack against that user. For example, gMail was susceptible to a JSON hijacking attack where a victim would visit the attacker’s website. The attacker’s website would issue a request to gMail for their contact list, and if the victim was already logged in, the attacker’s page would receive and parse the JSON, and finally submit the data back to the attacker’s server.

After authentication is in place, JSON hijacking protection can take a variety of forms. Google appends while(1) into their JSON data, so that if any malicious script evaluates it, the malicious script enters an infinite loop. Comment characters such as /* and */ should be sufficient to escape the entire string, rendering it unable to be evaluated. Using our example above, if the string read while(1); {"user": { "fname": "Paula", "lname":"Brilliant", "SSN": "078-05-1120" }, "accountNumber": "3157304449" }, then it would be protected—a script evaluating it would be stuck in an infinite loop.

JSON serialization is a way to transmit data in an easily parsed format. Javascript can parse JSON using the built-in eval() function, although this is discouraged. Using the eval() function without any other validation is a weakness that may be exploited by code injection. It’s not worth the risk, so people have now written full-fledged JSON parsers that include validation. You can find references to them at

Some websites are now purposefully offering public (non-confidential) data via JSON. They hope that other websites will read this data, in order to create mashups or other services. This recipe only really applies when the data being published is confidential or otherwise private. For example, Google’s gMail would reveal one’s address book contacts via JSON hijacking, which was an obvious vulnerability. Meanwhile, Reddit (a social news site) offers JSON feeds for nearly all of its public news feeds, which is just an additional feature. You can find Reddit’s JSON feed at
  •  Web Security : Attacking AJAX - Subverting AJAX with Injected XML, Subverting AJAX with Injected JSON
  •  .NET Security : Programming the Event Log Service (part 3) - Using Custom Event Logs, Monitoring Event Logs
  •  .NET Security : Programming the Event Log Service (part 2) - Reading Event Logs, Writing Events
  •  .NET Security : Programming the Event Log Service (part 1) - Querying the Event Log System, Using Event Sources
  •  .NET Security : The Event Log Service Explained
  •  Web Security : Attacking AJAX - Intercepting and Modifying Server Responses, Subverting AJAX with Injected Data
  •  Web Security : Attacking AJAX - Intercepting and Modifying AJAX Requests
  •  Hacker Zone (Part 2) - Take photos with your Bluetooth headset, Jargon Buster
  •  Hacker Zone (Part 1) - Build your own Cyanogen-Mod ROM with CMC, Manage files in Recovery Mode
  •  Hack Your Phone (Part 3)
    Top 10
    Review : Sigma 24mm f/1.4 DG HSM Art
    Review : Canon EF11-24mm f/4L USM
    Review : Creative Sound Blaster Roar 2
    Review : Philips Fidelio M2L
    Review : Alienware 17 - Dell's Alienware laptops
    Review Smartwatch : Wellograph
    Review : Xiaomi Redmi 2
    Extending LINQ to Objects : Writing a Single Element Operator (part 2) - Building the RandomElement Operator
    Extending LINQ to Objects : Writing a Single Element Operator (part 1) - Building Our Own Last Operator
    3 Tips for Maintaining Your Cell Phone Battery (part 2) - Discharge Smart, Use Smart
    - First look: Apple Watch

    - 3 Tips for Maintaining Your Cell Phone Battery (part 1)

    - 3 Tips for Maintaining Your Cell Phone Battery (part 2)
    - How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 1)

    - How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 2)

    - How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 3)
    Popular Tags
    Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Biztalk Exchange Server Microsoft LynC Server Microsoft Dynamic Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Indesign Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe After Effects Adobe Photoshop Adobe Fireworks Adobe Flash Catalyst Corel Painter X CorelDRAW X5 CorelDraw 10 QuarkXPress 8 windows Phone 7 windows Phone 8