42

What is the best defense against JSON hijacking?

Can anyone enumerate the standard defenses, and explain their strengths and weaknesses? Here are some defenses that I've seen suggested:

  1. If the JSON response contains any confidential/non-public data, only serve the response if the request is authenticated (e.g., comes with cookies that indicate an authenticated session).
  2. If the JSON data contains anything confidential or non-public, host it at a secret unguessable URL (e.g., a URL containing a 128-bit crypto-quality random number), and only share this secret URL with users/clients authorized to see the data.
  3. Put while(1); at the start of the JSON response, and have the client strip it off before parsing the JSON.
  4. Have the client send requests for JSON data as a POST (not a GET), and have the server ignore GET requests for JSON data.

Are these all secure? Are there any reasons to choose one of these over the others? Are there any other defenses I'm missing?

0

3 Answers 3

28

The first defence is to stick to the specification by using valid JSON which requires an object as top level entity. All known attacks are based on the fact that if the top level object is an array, the response is valid Java Script code that can be parsed using a <script> tag.

If the JSON response contains any confidential/non-public data, only serve the response if the request is authenticated (e.g., comes with cookies that indicate an authenticated session).

That's the pre requisite for the attack, not a mitigation. If the browser has a cookie for site A, it will include it in all requests to site A. This is true even if the request was triggered by a <script> tag on site B.

If the JSON data contains anything confidential or non-public, host it at a secret unguessable URL (e.g., a URL containing a 128-bit crypto-quality random number), and only share this secret URL with users/clients authorized to see the data.

URLs are not considered a security feature. All the common search engines have browser addons/toolbars that report any visited URL back to the search engine vendor. While they might only report URLs that are explicitly visited, I wouldn't risk this for JSON URLS either.

Have the client send requests for JSON data as a POST (not a GET), and have the server ignore GET requests for JSON data.

This will prevent the <script> include.

Put while(1); at the start of the JSON response, and have the client strip it off before parsing the JSON.

I suggest a modified version of this approach: Add </* at the beginning. while(1) is problematic for two reasons: First it is likely to trigger maleware scanner (on clients, proxies and search engine). Second it can be used for DoS attacks against the CPU of web surfers. Those attacks obviously originate from your server .

10
  • when it comes to authenticated data: Make sure to additionally use Challenge Tokens in your application against CSRF-attacks, this makes JSON Hijacking very hard.
    – GNi33
    Sep 10, 2011 at 0:00
  • 1
    @AndreyBotalov, no, it is not sufficient as there is still a large number of users out there which use browsers that still allow redefining of build in functions. Dec 9, 2011 at 21:57
  • 1
    @AndreyBotalov, the first hit on google is a document from 2007 naming Firefox 2, Opera 9, and Safari 3 as being vulnerable to the array redefinition. A bit further down is an article from 2009 naming Chrome 2.0.172.31 and Firefox 3.0.11 for the Object.prototype.__defineSetter__ attack. Spending a bit more time on this is likely to return more recent articles on more recent browsers. But as those old browser are still in use, this does not make much of a difference anyway. Dec 12, 2011 at 17:59
  • 7
    The spec does allow an array as a top level object - your post suggests though that this is not valid JSON. Your answer still stands though (+1) and having a top level object is (currently) secure against hijacking. Nov 21, 2013 at 12:10
  • 3
    An array as the top-level structure is very valid, see RFC 4627 for details. Most JSON parsers even consider primitive literals alone as valid JSON.
    – Bergi
    Feb 26, 2014 at 4:17
3

Google uses "unparseable cruft" to defend itself against this type of attack. This vulnerability was fixed in firefox 3. The vulnerability arises from how browsers implement the JSON specification.

2

1) If the JSON response contains any confidential/non-public data, only serve the response if the request is authenticated (e.g., comes with cookies that indicate an authenticated session). 2) If the JSON data contains anything confidential or non-public, host it at a secret unguessable URL (e.g., a URL containing a 128-bit crypto-quality random number), and only share this secret URL with users/clients authorized to see the data.

There's no good reason to do both (1) and (2).

The first is ABAC and the second is ZBAC. Trying to get defense-in-depth by using multiple access-control schemes is just over-complicating things.

3) Put while(1); at the start of the JSON response, and have the client strip it off before parsing the JSON.

4) Have the client send requests for JSON data as a POST (not a GET), and have the server ignore GET requests for JSON data.

These sounds like fine ideas and do add defense in depth since it helps ensure that credentials can't be misappropriated.

Additionally,

5) Only serve JSON with sensitive data over SSL or some other secure channel.

to prevent leaking data via MITM.

1
  • Question - see: sitepen.com/blog/2008/09/25/security-in-ajax - a different cruft method - and, does serving the json over SSL prevent hijacking and protection of the json data?
    – Jason
    Apr 26, 2012 at 17:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .