Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

I'm hesitant to implement the proposed anti-JSON hijacking solutions since

  1. The recommended solutions to mitigating JSON hijacking involve non-REST-full JSON POSTs to GET data

  2. The alternate solution (object wrapping) causes problems with 3rd party controls I don't have source-code access to.

  3. I can't find a community-vetted implementation that implements the Alternative Solution (listed below) on how to compose the security token, or securely deliver it within the webpage. I also won't claim to be enough of an expert to roll my own implementation.

  4. Referrer headers can't be relied upon

Background

This blog describes a CSRF issue regarding JSON Hijacking and recommends using JSON POSTs to GET data. Since using a HTTP POST to GET data isn't very REST-full, I'd looking for a more RESTfull solution that enables REST actions per session, or per page.

Another mitigation technique is to wrap JSON data in an object as described here. I'm afraid this may just delay the issue, until another technique is found.

Alternative Implementation

To me, it seems natural to extend the use ASP.NET MVC's AntiForgeryToken with jQuery HTTP GETs for my JSON.

For example if I GET some sensitive data, according to the Haacked link above, the following code is vulnerable:

$.getJSON('[url]', { [parameters] }, function(json) {
    // callback function code
});

I agree that it isn't RESTfull to GET data using the recommended POST workaround. My thought is to send a validation token in the URL. That way the CSRF-style attacker won't know the complete URL. Cached, or not cached, they won't be able to get the data.

Below are two examples of how a JSON GET query could be done. I'm not sure what implementation is most effective, but may guess that the first one is safer from errant proxies caching this data, thus making it vulnerable to an attacker.

http://localhost:54607/Home/AdminBalances/ENCODEDTOKEN-TOKEN-HERE

or

http://localhost:54607/Home/AdminBalances?ENCODEDTOKEN-TOKEN-HERE

... which might as well be MVC3's AntiForgeryToken, or a variant (see swt) thereof. This token would be set as an inline value on whatever URL format is chosen above.

Sample questions that prevent me from rolling my own solution

  1. What URL format (above) would you use to validate the JSON GET (slash, questionmark, etc) Will a proxy respond to http://localhost:54607/Home/AdminBalances with http://localhost:54607/Home/AdminBalances?ENCODEDTOKEN-TOKEN-HERE data?

  2. How would you deliver that encoded token to the webpage? Inline, or as a page variable?

  3. How would you compose the token? Built in AntiforgeryToken, or by some other means?

  4. The AntiForgeryToken uses a cookie. Would a backing cookie be used/needed in this case? HTTP Only? What about SSL in conjunction with HTTP Only?

  5. How would you set your cache headers? Anything special for the Google Web Accelerator (for example)

  6. What are the implications of just making the JSON request SSL?

  7. Should the returned JSON array still be wrapped in an object just for safety's sake?

  8. How will this solution interop with Microsoft's proposed templating and databinding features

The questions above are the reasons I'm not forging ahead and doing this myself. Not to mention there likely more questions I haven't thought of, and yet are a risk.

share|improve this question
    
Poked to try to get some answers... –  AviD Mar 7 '11 at 21:38
    
what are you looking for? –  Rook Mar 2 '12 at 3:33

2 Answers 2

up vote 2 down vote accepted

This technique was pioneered by Jeremiah Grossman. This was only an issue because the returned json also contains javascript which could be included into a page via a <script> tag. Most json responses cannot be abused this way because the same-origin policy forbids javascript from fetching the results. To patch this issue Google used an unparseable cuft.

share|improve this answer

This paper summarizes a variety of reasonable defenses.

Including an unpredictable token in the URL is indeed a reasonable way to defend against the threat. (See Section 3 of the paper for mention of this.) One reasonable way to deliver it to the server is as a parameter. The token might be a copy of the session cookie, or a secret value that's known to the server and cannot be predicted by an attacker. The techniques for implementing this are probably very similar to those for defending against CSRF.

I think HTTP vs HTTPS is an orthogonal issue; I don't see any relevance here.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.