MacPython Logo from __future__ import *

2007-04-05

Fortify JavaScript Hijacking FUD

Filed under: AJAX, MochiKit, javascript — bob @ 9:49 am

Recently, Fortify Software has claimed that there is a pervasive and critical vulnerability in Web 2.0 with their JavaScript Hijacking paper. The way they wrote the paper is extremely misleading and was likely constructed this way on purpose to garner press and business for their company.

The first egregious dishonesty in their paper is that it analyzes client-side Ajax frameworks. This is not where the vulnerability is, nor where it's fixed. The service's intended client-side JavaScript code is not even executed during ANY PART of the demonstrated exploit! However, client-side Ajax frameworks are a hot topic, so what the hell, let's blame them.

The second is that they do not enumerate all of the preconditions required for the exploit. The client must support JavaScript setters. The only browser that I've found that supports these are Firefox. Internet Explorer 6, Safari, and Opera are NOT VULNERABLE to the specific exploit described in the paper. The paper claims that "all of the examples in the paper could be adapted to work under Internet Explorer too". Oh yeah? Prove it.

And MOST importantly the exploit is only applicable to JSON that also happens to be valid JavaScript code. The only type of JSON that is valid JavaScript code without parentheses is a JavaScript array (or bare primitives, but those are not interesting or exploitable). That's right, the simplest fix is to always make sure you send an object on the outside, not an array.

Exploitable:

[{"object": "inside an array"}]

NOT Exploitable:

{"object": "not inside an array"}

Also NOT Exploitable:

{"result": [{"object": "inside an array"}]}

The simplest solution is to just change the JSON RFC to include a strong recommendation that only objects should be allowed as an envelope. Server-side frameworks should give error or provide warning when an array is serialized without a containing object. I notified them of this before the paper was published, but they ignored my suggestion and instead went for the more complicated suggestion of trying to add backwards-incompatible sludge to JSON.

I've crafted a little example that shows which browser you're using and the attacks that were successful. The Fortify exploit is "Array/Object JSON vulnerable". The two other tests are for JSON documents not contained by an array. The Fortify exploit is the only one that succeeds, and it only succeeds in Firefox.

17 Comments »

  1. Mutable Object is just so darn lame.

    On the server side, I wonder if there’s something obvious in the Accept header (or elsewhere) that could distinguish a “proper” request? Or simply checking the Referer header would do it, wouldn’t it?

    Comment by Ian Bicking — 2007-04-05 @ 7:10 pm

  2. There’s a lot of ways to do it server-side. One of which is *send objects as your envelope*. Not so hard.

    Comment by bob — 2007-04-05 @ 7:29 pm

  3. I love in the FAQ that one one had they say…

    “If the security of your program depends on your choice of data structures, you’re on thin ice.”

    then 3 FAQ’s later they say…

    “Other formats that use JavaScript syntax are potentially vulnerable too, but XML is not vulnerable”

    So they’re saying that choosing an XML data structure is an OK security fix, but depending on a data structure for security is thin ice.

    I know what they’re saying, but that is a great mixed message.

    There is definitely a fair amount of FUD going on with some of this JSON exploit excitement. Some of it is fair game. A good differentiator between good web service company and bad is things like security. So with the increased popularity of JSON if Company A can shout loud enough about it, and Company B doesn’t - it’s a good way for A to make themselves seen as better.

    Eventually everyone will just expect these fixes, and it’ll stop being a differentiating factor - like storing passwords in human readable states - no one ’should’ be doing that these days, everyone knows that, which I why we’re not seeing a million blog posts about why you shouldn’t.

    I totally agree about some people publishing white-papers or blog posts when they don’t even have real world examples of the exploits working.

    It was one of the things I wanted to do with my post on the subject….

    http://jpsykes.com/47/practical-csrf-and-json-security

    …take all the examples and actually make a cross domain demonstration of the techniques.

    Comment by JP — 2007-04-06 @ 10:31 am

  4. JP - why is the suggestion of using xml a “mixed message”? xml has no defined default executable model. it is not subject to this exploit. what is so confusing? bob is correct that object-as-envelope is a fix, but thats just more lore-based programming for js…if you don’t know the lore, you’re subject to the exploit.

    Comment by whoopee — 2007-04-06 @ 12:06 pm

  5. The mixed message is saying “you can’t depend on a data structure for security” and then saying “using the XML data structure is secure”. As I said, I know what they’re saying, it’s just with a whitepaper someone who doesn’t know the ins and outs could find those two statements contradictory.

    Comment by JP — 2007-04-06 @ 12:23 pm

  6. Excellent post with good PoC! It’s not always easy to differcuate between real XSS/CSRF security problems and the marketing jibber-jabber of the security companies - your article helped out on this area.

    Greetings,
    .mario

    Comment by .mario — 2007-04-07 @ 6:40 am

  7. Hey bob, not sure if you’ve seen it, but Ars Technica has a “great” article on this…

    http://arstechnica.com/news.ars/post/20070404-study-finds-that-ajax-toolkits-dont-protect-against-javascript-security-vulnerabilities.html

    It’s like screaming fire in a crowded theater. ;-)

    Comment by JP — 2007-04-11 @ 8:05 am

  8. whopee - XML isn’t a data structure, and doesn’t define one. So they are right.

    XML is a serialized representation of structured information. Since a data structure is an (non-serialized) example of structured information, you can represent arbitrary data structures in XML, with more or less work, but the resulting XML is a serialized representation of the data structure, it is not the data structure. If it sounds like I’m splitting hairs, consider the difference between a photograph of a gun and a gun :-)

    Liam (W3C XML Avtivity Lead

    Comment by Liam Quin — 2007-04-14 @ 12:28 pm

  9. You are splitting hairs… JSON is a serialized representation of a data structure too, and it’s equivalent to XML (anything you do with XML you can do with JSON and vice versa).

    Comment by bob — 2007-04-14 @ 1:25 pm

  10. Hi Bob, I’m Brian Chess, one of the authors of the JavaScript Hijacking paper. You sound a little bitter. I can’t say I blame you. Programming is easier when you don’t have to think about security, and the Ajax community has gotten away without thinking very much about security for a few years now. Want some evidence? Go look at the documentation for any of the major frameworks that shows programmers how to use the framework in a secure way. It won’t take you long to read because there’s pretty much zero.

    We’d like to get Ajax programmers having explicit conversations about security *now* so that we don’t have another mess to clean up starting in a few years after people have unknowingly written a tremendous amount of vulnerable code.

    As for your critique, I think you’ve fallen into a number of common boondoggles. First, we’re talking about JavaScript Hijacking, not JSON hijacking. JSON is not the only way people are using JavaScript as a data transport format. Take a look at the JSArray representation offered by Yahoo (vulnerable) or the pre-2.0 DWR callback format (highly vulnerable).

    Another common mistake is to believe that the client-side frameworks have nothing to do with the security of the server. It’s sort of like saying that your peer group has nothing to do with your behavior. If the client side frameworks continue to support dangerous practices without any warning to the programmer, they are at best complicit in the creation of vulnerable software. Used in their default configuration, some client-side frameworks (MochiKit is a prime example) actually *require* the creation of a vulnerable server.

    I do think it’s reasonable to consider alternatives to the fixes that we proposed. Changing JSON so that it explicitly made provisions for security would be great. At the same time, people are using JSON as it exists today, and they deserve to understand the security risks they face.

    Thanks,
    Brian

    Comment by Brian Chess — 2007-04-18 @ 9:30 am

  11. Brian, are you literate? It certainly doesn’t seem like you actually read the post. I’m well aware of what secure code is and how it’s done and that’s not what bothers me about you, your paper, and the reaction to it.

    Why the hell should there be security documentation in client frameworks? The security documentation should be in the web frameworks, because that’s where it needs to be implemented. Any security documentation with client frameworks would be purely supplemental.

    I offered a much simpler solution that is secure and is still valid JSON and requires no changes to any client, simply restricting the response to a particular (and already extremely common) subset of JSON is sufficient.

    The representation offered by Yahoo is explicitly for cross-domain use, I don’t see relevancy.

    Comment by bob — 2007-04-18 @ 9:38 am

  12. >I offered a much simpler solution that is secure and is still valid JSON and requires no changes to any client, simply
    > restricting the response to a particular (and already extremely common) subset of JSON is sufficient.

    (Assuming your solution is telling users to only use plain objects)

    That’s like telling developers not to code buffer overflows. We all see how well that works… As a framework provider, if you’re capable of distributing a framework that helps in making code more secure, why wouldn’t you? (Yes, I know you have patched after being nagged to death by your users.)

    All too often devs that nit pick security issues are proven wrong time and time again by tenacious hackers. Error on the safe side.

    Comment by fk — 2007-04-18 @ 11:17 pm

  13. The solution is to make JSON producers warn if they’re serializing an array envelope. It’s not anything like telling developers not to code buffer overflows. It’s like telling them not to use eval.

    NOTHING MochiKit can do is insecure (in this way). Whatever the client sends or decodes is irrelevant. It’s a 100% server-side issue. I added comment stripping support so that people would shut up, not because it’s useful in theory or practice.

    Tricking a JS implementation to deserialize invalid JavaScript syntax (an object envelope) is just as intractable as getting one to strip comments or a while (1). It doesn’t even parse, the grammar does not allow it. I don’t care how tenacious hacker is, they would need a full text exploit vector to do it, which makes it exactly as secure as any of the other proposed solutions except it’s infinitely easier to implement since it does not require a new specification or any implementation changes.

    Comment by bob — 2007-04-18 @ 11:34 pm

  14. How json-particular is this hijacking trick? I wonder, couldn’t a similar technique be applied to a callback service that returned data in xml? If instead of using a script one where to use an iframe with an src pointing towards the service to be hijacked. The returned xml would be (let’s assume a very tolerant x/html doctype) inlined into the dom? What is then to stop the malicious page from manipulating that dom, and ajaxing the hijacked data off to another server? This *should* not work… what guarantees that it does not?

    Comment by mario — 2007-04-20 @ 1:10 am

  15. The browser’s same origin policy guarantees it.

    Comment by bob — 2007-04-20 @ 8:30 am

  16. While I have not researched this whole discussion in depth, I am inclined to agree with you at this point. However, I have thought about the “same origin policy” before and have a question that, again, I have not researched nor tested. If I am not mistaken, the “same origin” is based on the domain name of the resources in question. Let’s say I find a server/page that I wanted to initiate a scripting attack against (as in post 14). I also get the IP address that the domain is pointing to (for use in just a minute). Now I disconnect from the Net, create a web site on my local server with the domain name in question, add the IP address to my NIC and point it to the site on my local server. I create a page that has an iframe with the src pointing to the page I want to attack (which I have also created on my local server). The containing page (not the iframe src) has the necessary script, etc. to launch the attack and the iframe is pointing to a “same origin” resource since they both reside on my local server. I fire up my browser point to the spoofed page. The “gun is loaded” but it is “aimed” at my local server, which does not do much good. So what do I do? I take my local server offline and reconnect to the Net so that the domain and IP will resolve at the original server. Now the “gun” is aimed at the server I want to attack. I click on the “Fire” button and the script runs and launches my attack, which the browser and the server think is OK because everything is “same origin”. Since I not only spoofed the domain name but the IP as well, there is no way that either party involved (my browser nor the other server) knows that the pages actually originated elsewhere. It seems such an easy way to circumvent the “same origin” policy that I hope I am just not educated well enough to understand what would stop that. Either that, or the FBI / CIA is going to be knocking on my door in the next day or two. :-) (I swear, I have never tried this. Obviously, because if I had and was “blocked” I would know that it is not possible. Alternatively, if I knew my idea would work, do think I would be posting it in a public forum like this?)

    Comment by Andrew — 2007-07-23 @ 10:28 pm

  17. The same origin policy is not there to protect someone from themselves, but to protect them from going to a third party site and unknowingly having bad things happen. There are an infinite number of ways you could do “bad” things if you had full control over the computer in question.

    Comment by bob — 2007-07-23 @ 11:16 pm

RSS feed for comments on this post.

Leave a comment

Powered by WP Hashcash

Powered by WordPress