title: Using MVC3's AntiForgeryToken in HTTP GET to avoid Javascript CSRF vulnerability
body: <p><a href="http://haacked.com/archive/2009/06/25/json-hijacking.aspx">In regards to this Haacked blog</a>, I'm hesitant to implement the proposed anti-JSON GET hijacking solutions since </p>
  
  <ol>
  <li><p>The recommended solutions to mitigating JSON hijacking involve non-REST-full JSON POSTs to GET data </p></li>
  <li><p>The alternate solution (object wrapping) causes problems with 3rd party controls I don't have source-code access to.</p></li>
  <li><p>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.</p></li>
  <li><p>Referrer headers can't be relied upon</p></li>
  </ol>
  
  <p><strong>Background</strong></p>
  
  <p><a href="http://haacked.com/archive/2009/06/25/json-hijacking.aspx">This blog</a> 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.</p>
  
  <p>Another mitigation technique is to wrap JSON data in an object <a href="http://mhinze.com/2010/04/13/json-hijacking-in-asp-net-mvc-2/">as described here</a>.  I'm afraid this may just delay the issue, until another technique is found.</p>
  
  <p><strong>Alternative Implementation</strong></p>
  
  <p>To me, it seems natural to extend the use <a href="http://davidhayden.com/blog/dave/archive/2009/04/29/AntiForgeryTokenInMVCFramework.aspx">ASP.NET MVC's AntiForgeryToken</a> with jQuery HTTP GETs for my JSON.</p>
  
  <p>For example if I GET some sensitive data, according to the Haacked link above, the following code is vulnerable:</p>
  
  <pre><code>$.getJSON('[url]', { [parameters] }, function(json) {
      // callback function code
  });
  </code></pre>
  
  <p>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.  </p>
  
  <p>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.</p>
  
  <p><a href="http://localhost:54607/Home/AdminBalances/ENCODEDTOKEN-TOKEN-HERE">http://localhost:54607/Home/AdminBalances/ENCODEDTOKEN-TOKEN-HERE</a></p>
  
  <p>or</p>
  
  <p><a href="http://localhost:54607/Home/AdminBalances?ENCODEDTOKEN-TOKEN-HERE">http://localhost:54607/Home/AdminBalances?ENCODEDTOKEN-TOKEN-HERE</a></p>
  
  <p>... which might as well be MVC3's AntiForgeryToken, or a variant (<a href="http://blogs.msdn.com/b/rockyh/archive/2010/04/15/azure-access-control-service-client-patterns-part-1.aspx">see swt</a>) thereof.  This token would be set as an inline value on whatever URL format is chosen above.</p>
  
  <p><strong>Sample questions that prevent me from rolling my own solution</strong></p>
  
  <ol>
  <li><p>What URL format (above) would you use to validate the JSON GET  (slash, questionmark, etc)  Will a proxy respond to <a href="http://localhost:54607/Home/AdminBalances">http://localhost:54607/Home/AdminBalances</a> with <a href="http://localhost:54607/Home/AdminBalances?ENCODEDTOKEN-TOKEN-HERE">http://localhost:54607/Home/AdminBalances?ENCODEDTOKEN-TOKEN-HERE</a> data?</p></li>
  <li><p>How would you deliver that encoded token to the webpage?  Inline, or as a page variable?</p></li>
  <li><p>How would you compose the token?  Built in AntiforgeryToken, or by some other means?</p></li>
  <li><p>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?</p></li>
  <li><p>How would you set your cache headers?  Anything special for the Google Web Accelerator (for example) </p></li>
  <li><p>What are the implications of just making the JSON request SSL?</p></li>
  <li><p>Should the returned JSON array still be wrapped in an object just for safety's sake?</p></li>
  <li><p>How will this solution interop with Microsoft's proposed <a href="http://weblogs.asp.net/scottgu/archive/2010/07/27/introducing-asp-net-mvc-3-preview-1.aspx">templating and databinding</a> features</p></li>
  </ol>
  
  <p>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.</p>