The real reason for (JavaScript|JSON) Hijacking

Published 27 August 07 01:59 PM | Billy 

When JSON hijacking was first discussed and demonstrated in 2006 and 2007 by Whitehat, Fortify and others, all of the proof of concepts used Mozilla specific JavaScript extensions like setter or __defineSetter__. This led many people to believe that these vulnerabilities only existed in Mozilla-derived browsers like Firefox because only those browsers supported extensions like __defineSetter__. Brian Chess tempted me when he made an offhand comment in Fortify's paper that there was a way to performing hijacking against IE. However after an email exchange I learned that Chess et all were unable to actually hijacking IE.

When performing some research for my upcoming Ajax Security book, I wanted to see if I could find a way to perform this attack against users of IE. I started poking at this quite a bit and learned some interesting things. First of all, I needed a way to hijack the Array() and Object() constructor functions in a non-Mozilla specific way. I was able to expand on Joe Walkers approach and came up with the following:

function Array() {
    var foo = this;
    var bar = function() {
        var ret = "Captured array items are: [";
        for(var x in foo) {
            ret += foo[x] + ", ";
        }
        ret += "]";
        //notify an attacker. Here we just display it
        alert(ret);    
    };
     setTimeout(bar, 100);
}

We use anonymous functions and a closure to persist scope for our setTimeout() call. Renaming this function to Object will hijack the object constructor. Awesome. So I have a proof of concept that doesn't use Mozilla specific extensions. This should work in IE right? The answer is no, it still only works in Mozilla. To understand, think about the two conditions that make JSON API hijacking possible:

  1. JSON array literals and (properly enclosed) object literals returned by Ajax endpoints are valid JavaScript
  2. The JavaScript interpreter automatically calls the array or object constructor when it encounters the appropriate literal.

Of these two reasons, there is nothing that can be done about #1. Indeed, JSON was deliberately designed to be a subset of JavaScript to ease its parsing through the use of the eval() function. However, reason #2 is specific to each browser’s JavaScript interpreter. The authors tested the major browsers and concluded that the JavaScript interpreter in Mozilla derived browsers is the only JavaScript interpreter which invokes the array or object constructors when a literal is encountered! Only by literally calling the constructor function with the new keyword such as var obj = new Object(); or  var array = new Array(); will other browser actually invoke the appropriate constructor!

So it turns out that Mozilla derived browsers (such as Mozilla, Firefox, Netscape, IceWeasel, etc) are still the only browsers vulnerable to JSON hijacking, but for a completely different reason that previously believed!

 

Filed under: , , ,

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# Aditya K Sood said on August 28, 2007 4:33 AM:
As per your view the JSON infection is based on object design infection. For this a single object like A with name and value pair stats. Possiblity or its sure passing a script or an injection in value of an object can serialize it. Thats a point of infection. To your point you need a browser to render the DOM to present it to user as such. As the browser dependency related to I.E or Mozilla , the object consistency should be there to uphold that concept of JSON Hijacking. So a browser should support a that type of object rendering that is required for creation of arrays and objects for hijacking.

Leave a Comment

(required) 
(optional)
(required) 

About Billy

Billy Hoffman is the lead researcher for SPI Labs.