SpiderLabs Blog

JSON Hijacking Demystified

Written by Rohini Sulatycki | Sep 24, 2012 1:29:00 PM

JavaScript Object Notation (JSON) is a language and platform independent format for data interchange. JSON is in widespread use with a number of JSON parsers and libraries available for different languages. While some information is available for JSON hijacking this attack is not very well understood.

JSON Hijacking as the name suggests is an attack similar to Cross-Site Request Forgery where an attacker can access cross-domain sensitive JSON data from applications that return sensitive data as array literals to GET requests. An example of a JSON call returning an array literal is shown below:

[{"id":"1001","ccnum":"4111111111111111","balance":"2345.15"},{"id":"1002","ccnum":"5555555555554444","balance":"10345.00"},{"id":"1003","ccnum":"5105105105105100","balance":"6250.50"}]

This attack can be achieved in 3 major steps:

  • Step 1: Get an authenticated user to visit a malicious page.
  • Step 2: The malicious page will try and access sensitive data from the application that the user is logged into. This can be done by embedding a script tag in an HTML page since the same-origin policy does not apply to script tags.
    <script src="http://<jsonsite>/json_server.php"></script>
  • The browser will make a GET request to json_server.php and any authentication cookies of the user will be sent along with the request.
  • Step 3: At this point while them alicious site has executed the script it does not have access to any sensitive data. Getting access to the data can be achieved by using an object proto typesetter. In the code below an object prototypes property is being bound to the defined function when an attempt is being made to set the "ccnum" property.

Object.prototype.__defineSetter__('ccnum',function(obj){

secrets =secrets.concat(" ", obj);

});

  • At this point the malicious site has successfully hijacked the sensitive financial data (ccnum) returned byjson_server.php

It should be noted that not all browsers support this method; the proof of concept was done on Firefox 3.x.This method has now been deprecated and replaced by the useObject.defineProperty There is also a variation of this attack that should work on all browsers where full named JavaScript (e.g. pi=3.14159) is returned instead of a JSON array.

There are several ways in which JSON Hijacking can be prevented:

  • Since SCRIPT tags can only generate HTTP GET requests, only return JSON objects to POST requests.
  • Prevent the web browser from interpreting the JSON object as valid JavaScript code.
  • Implement Cross-Site Request Forgery protection by requiring that a predefined random value be required for all JSON requests.