1

Closed

JSON Requests and AntiForgeryToken

description

I am developing a site which will use JSON requests from the client for most of the transactions. Among other security considerations, it would be useful to have MVC accept an AntiForgeryToken as part of each transaction. For now, I have created a rather ugly hack to permit submission of JSON data along with an AntiForgeryToken. By adding a ValidateJsonAntiForgeryTokenAttribute class, and making a minor modification to the JsonValueProvider class, it would be possible to pass __RequestVerificationToken back with each JSON request, and have the appropriate validation executed. The only caveat would be that the __RequestVerificationToken could not be nested inside of any other element in the model, based on the implementation attached. This modification is much more easily accomplished within MVC than by my trying to write external classes. Thanks.

I realize (with a red face) that my code will not work, because I did not reset the position of controllerContext.HttpContext.Request.InputStream after the StreamReader is opened, since I am now consuming the stream twice. The following line of code:
    controllerContext.HttpContext.Request.InputStream.Position = 0;
must be added after:
    StreamReader reader = new StreamReader(controllerContext.HttpContext.Request.InputStream);

file attachments

Closed Nov 12, 2010 at 5:00 PM by
By design.

comments

auriel wrote Nov 4, 2010 at 8:45 PM

The AntiForgeryToken is only useful to prevent XSRF-based exploits. Since JSON requests can only originate from the same host (browsers don't allow cross-host XmlHttpRequest), such requests are generally not candidates for anti-XSRF protection. Can you explain a little more what your particular scenario is?

counsellorben wrote Nov 4, 2010 at 11:56 PM

Here is my concern:

Consider the scenario from Phil Haack's article, http://haacked.com/archive/2009/04/02/anatomy-of-csrf-attack.aspx, up through the point where the attacker's form would POST.
  1. Tthe attacker does not let the cross-site form post, but traps the post with a script.
  2. The script on the page parses the post to obtain the authorization cookie (and any cookies the valid site may use).
  3. The script instead sends the cookie to a server controlled by the attacker.
  4. Now, until the expiration of the compromised cookie, the attacker can construct and send out any JSON request within the scope of authority of the affected user, unless there is a secondary means of authentication.
The theft of the cookies would allow the attacker to bootstrap a further attack, without a further means of defense.

auriel wrote Nov 5, 2010 at 7:12 AM

Step (2) of your attack cannot take place. Even if you get me to go to evil.com (which you control) and generate a form which posts to mybank.com, and even if evil.com uses Javascript to inspect the form post going to mybank.com, the browser won't let evil.com inspect anything other than the form contents themselves. Specifically, cookies (including the authorization cookie) for mybank.com will not be available to evil.com. Browsers must enforce this behavior, otherwise any site could inspect any other arbitrary site's cookies in your browser.

counsellorben wrote Nov 5, 2010 at 3:02 PM

I understand your point, but I am still concerned about a theoretical risk of stealing the authorization cookie, as described at http://www.articlealley.com/article_1503308_11.html. I will work on a proof of concept over the weekend.

auriel wrote Nov 5, 2010 at 4:26 PM

If you can steal a user's authorization cookie, it's game over. You could then just log into that user's account directly without messing around with the anti-XSRF token. Normally you'll find that when authorization tokens are stolen it's the result of an XSS attack. We try to help prevent XSS automatically (via request validation and HTML-encoding our helpers' output), but ultimately it's up to the web site developer to guard against these attacks.

counsellorben wrote Nov 24, 2010 at 10:01 AM

I have attached a demo of an exploit targeting an action returning JsonResult, along with a filter attribute to aply to such actions to mitigate the risk.

counsellorben wrote Nov 24, 2010 at 11:09 AM

This is what comes of coding while sleep deprived. I changed the JsonRequestFilter to an authorization filter, and generated a substitute response. The updated filter is attached.

auriel wrote Nov 24, 2010 at 5:34 PM

Continuing this discussion at http://forums.asp.net/t/1624454.aspx.