As far as I know there is no way to get the ValidateAntiForgeryTokenAttribute to work with a controller action that is using model binding to JSON. I tried adding the __RequestVerificationToken property to the JSON object before posting but it didn't pass
the verification.
This is by design. The anti-forgery stuff is meant to help prevent XSRF attacks, which are not possible when posting JSON to the server. See
http://aspnet.codeplex.com/workitem/7472 for more information.
Marked as answer by adyoung on Nov 19, 2010 12:54 AM
This is by design. The anti-forgery stuff is meant to help prevent XSRF attacks, which are not possible when posting JSON to the server. See
http://aspnet.codeplex.com/workitem/7472 for more information.
Please review the updates I posted to this workitem.
There is a vulnerability regarding JSON requests. Specifically, an "application/x-www-form-urlencoded" request which returns data in a format acceptable to your Action can be used to mount an XSRF attack, since MVC does not validate the form of the request.
The upshot is that the attacker can trigger the Action which expects JSON input and returns a JsonResult without using an XmlHttpRequest, especially if the model you are binding to is flat.
The risk can be mitigated by an AuthorizeAttribute filter applied to your Action, to validate that the request is an "application/json" request.
Thanks for your feedback. We did consider this when generating the threat model for this feature and found it to be an acceptable risk, as it doesn't fit the specific attack we're trying to mitigate. As you point out, there are steps the developer can
take to ensure that the incoming request truly is a JSON request.
Marked as answer by ricka6 on Nov 24, 2010 11:15 PM
I understand now that my original request for an ability to verify an AntiForgeryToken for JSON requests is not the primary means of mitigation for the risk. Further, because I have identified the threat, I am now protected. However, I am uncertain that
many developers are currently aware that MVC Actions returning JSON, AJAX and XML are vulnerable to being invoked in a manner permitting an XSRF attack.
The original response I received to the workitem was that JSON is an XmlHttpRequest, so the risk of an XSRF attack does not exist. As my proof-of-concept shows, this is not correct.
Developers need to be made aware that, because of the agnostic nature in which MVC Actions can be invoked, there is a risk unless you verify that your Action is being invoked via an XmlHttpRequest.
I disagree with your statement about being invoked in a manner permitting XSRF, but I think that's because I'm using a slightly different definition of what it means to invoke the method. For simplicity, let's narrow it to two and say that action methods
can be invoked via XHR or via form POST. The former (XHR) is not vulnerable to XSRF for the reasons given here and in the CodePlex work item. The latter (form POST) is vulnerable to it, and that's what the [ValidateAntiForgeryToken] attribute shuts down.
Our anti-XSRF functionality is not applicable to and does not work with XHR invocations. This is what is accounted for in our threat model, and this is why we do not see it as a vulnerability in MVC.
The [ValidateAntiForgeryToken] attribute will throw on an XHR invocation, so this is still secure by default. However, if a developer expects an XHR invocation
and removes that attribute as a result, he has to take manual steps to ensure that the incoming request truly is via XHR. This is no different than securing any other action method against unintended or malicious invocation. A filter like the one you
created would be appropriate for this.
Your point about potentially catching developers by surprise is sound, though. I can bring up with the rest of the team as to whether such a filter might be appropriate for in-box inclusion in the product and if any of our other automated behavior should
change.
Marked as answer by ricka6 on Nov 24, 2010 11:15 PM
The [ValidateAntiForgeryToken] attribute will throw on an XHR invocation, so this is still secure by default. However, if a developer expects an XHR invocation
and removes that attribute as a result, he has to take manual steps to ensure that the incoming request truly is via XHR. This is no different than securing any other action method against unintended or malicious invocation. A filter like the one you
created would be appropriate for this.
Levi,
I may sound as if I am picking at nits, but my original issue (and the original topic of this post) was that the ValidateAntiForgeryToken attribute cannot be used with JSON requests, because the __RequestVerificationToken cannot be passed back in JSON, since
the JSON data is not read into the backing store until AFTER the attempt has been made to validate the AntiForgeryToken. As a result, it is not possible to use the ValidateAntiForgeryToken attribute with a JSON request, because the __RequestVerificationToken
does not exist when the OnAuthorization event occurs. The out-of-the-box ValidateAntiForgeryToken attribute will always throw a CreateValidationException() on a JSON request.
So it is not that a developer will intentionally remove the ValidateAntiForgeryToken attribute on an Action returning JsonResult, it is that the ValidateAntiForgeryToken attribute will cause the request to fail, so the developer
must remove it. By necessity, these Actions are left naked and vulnerable UNLESS the developer ensures the request is XHR. Prior to my insight in the wee small hours of the morning, I would have concluded that my code was secured against a confused
deputy attack, since I have the ValidateAntiForgeryToken attribute for all of my Actions returning ActionResults, and everything else (supposedly) operates via XHR.
It was my bone-headed misunderstanding that made me think it was necessary to use the ValidateAntiForgeryToken attribute for this situation, but I was correct in my original assessment of a threat of a confused deputy attack against Actions returning JsonResults.
(I may just have injured myself with that pat on the back).
Yes, the developer must remove it. The act of removing it should be a huge red flag that manual steps are necessary to secure the application.
Your description makes it sound like it's a vulnerability that the JSON blob doesn't contain the anti-XSRF token. It's not necessary or useful for the JSON blob, XML blob, or any other blob to contain any anti-XSRF token, since by definition those blobs
can only come from the same host. The only thing that could come from a different host is the form post body, so that's what we check. It is simply not possible to mount an XSRF attack with XHR.
I think we're narrowing the focus of our discussion, though, and I think we're coming to an agreement. Specifically, your new concern is that the MVC framework makes it too easy to write actions that are meant to be XML-only, JSON-only, etc., but which
are in fact more generally callable. Am I understanding your new concern correctly? If so, I agree with these points, and I'll be following up with the rest of the team on how we can make these better.
Marked as answer by ricka6 on Nov 24, 2010 11:15 PM
I think we're narrowing the focus of our discussion, though, and I think we're coming to an agreement. Specifically, your new concern is that the MVC framework makes it too easy to write actions that are meant to be XML-only, JSON-only, etc., but which are
in fact more generally callable. Am I understanding your new concern correctly? If so, I agree with these points, and I'll be following up with the rest of the team on how we can make these better.
Levi,
Yes, you expressed it very well. It is my concern that actions which the developer expects to be invoked via XHR can be invoked via POST, and therefore are vulnerable to a confused deputy attack.
There seems to be a generalized belief in the developer community that these types of actions are BY THEIR VERY NATURE secured against confused deputy attacks, and no action is necessary. That in fact was the response to my original request, and the original
resolution to this post.
You can be certain that some black hats already knew of this attack vector, so it is incumbent upon us (well ... you and the rest of the MVC team, really, since you have the bully pulpit) to do what we (uhh ... you) can to make the developer community aware
of this vulnerability. I believe that your earlier suggestion to include some built-in AuthorizationAttribute filters in MVC is an excellent idea, maybe by expanding the JsonRequestAttribute filter I tossed off into a more generalized XhrRequestAttribute
filter. I also believe that some code examples to make developers aware of this issue should be disseminated.
adyoung
Member
1 Points
3 Posts
MVC3 JSON Model binding not working with AntiForgery
Nov 17, 2010 10:33 PM|LINK
As far as I know there is no way to get the ValidateAntiForgeryTokenAttribute to work with a controller action that is using model binding to JSON. I tried adding the __RequestVerificationToken property to the JSON object before posting but it didn't pass the verification.
Will there be built in support for this?
levib
Star
7702 Points
1099 Posts
Microsoft
Re: MVC3 JSON Model binding not working with AntiForgery
Nov 18, 2010 05:08 AM|LINK
This is by design. The anti-forgery stuff is meant to help prevent XSRF attacks, which are not possible when posting JSON to the server. See http://aspnet.codeplex.com/workitem/7472 for more information.
adyoung
Member
1 Points
3 Posts
Re: MVC3 JSON Model binding not working with AntiForgery
Nov 19, 2010 12:56 AM|LINK
Thank you for pointing this out. That should have been obvious to me even before I started going down this road. :)
counsellorbe...
Member
540 Points
112 Posts
Re: MVC3 JSON Model binding not working with AntiForgery
Nov 24, 2010 01:40 PM|LINK
Please review the updates I posted to this workitem.
There is a vulnerability regarding JSON requests. Specifically, an "application/x-www-form-urlencoded" request which returns data in a format acceptable to your Action can be used to mount an XSRF attack, since MVC does not validate the form of the request. The upshot is that the attacker can trigger the Action which expects JSON input and returns a JsonResult without using an XmlHttpRequest, especially if the model you are binding to is flat.
The risk can be mitigated by an AuthorizeAttribute filter applied to your Action, to validate that the request is an "application/json" request.
counsellorben
levib
Star
7702 Points
1099 Posts
Microsoft
Re: MVC3 JSON Model binding not working with AntiForgery
Nov 24, 2010 04:10 PM|LINK
Ben -
Thanks for your feedback. We did consider this when generating the threat model for this feature and found it to be an acceptable risk, as it doesn't fit the specific attack we're trying to mitigate. As you point out, there are steps the developer can take to ensure that the incoming request truly is a JSON request.
counsellorbe...
Member
540 Points
112 Posts
Re: MVC3 JSON Model binding not working with AntiForgery
Nov 24, 2010 04:37 PM|LINK
Levi,
I understand now that my original request for an ability to verify an AntiForgeryToken for JSON requests is not the primary means of mitigation for the risk. Further, because I have identified the threat, I am now protected. However, I am uncertain that many developers are currently aware that MVC Actions returning JSON, AJAX and XML are vulnerable to being invoked in a manner permitting an XSRF attack.
The original response I received to the workitem was that JSON is an XmlHttpRequest, so the risk of an XSRF attack does not exist. As my proof-of-concept shows, this is not correct.
Developers need to be made aware that, because of the agnostic nature in which MVC Actions can be invoked, there is a risk unless you verify that your Action is being invoked via an XmlHttpRequest.
counsellorben
levib
Star
7702 Points
1099 Posts
Microsoft
Re: MVC3 JSON Model binding not working with AntiForgery
Nov 24, 2010 04:58 PM|LINK
I disagree with your statement about being invoked in a manner permitting XSRF, but I think that's because I'm using a slightly different definition of what it means to invoke the method. For simplicity, let's narrow it to two and say that action methods can be invoked via XHR or via form POST. The former (XHR) is not vulnerable to XSRF for the reasons given here and in the CodePlex work item. The latter (form POST) is vulnerable to it, and that's what the [ValidateAntiForgeryToken] attribute shuts down. Our anti-XSRF functionality is not applicable to and does not work with XHR invocations. This is what is accounted for in our threat model, and this is why we do not see it as a vulnerability in MVC.
The [ValidateAntiForgeryToken] attribute will throw on an XHR invocation, so this is still secure by default. However, if a developer expects an XHR invocation and removes that attribute as a result, he has to take manual steps to ensure that the incoming request truly is via XHR. This is no different than securing any other action method against unintended or malicious invocation. A filter like the one you created would be appropriate for this.
Your point about potentially catching developers by surprise is sound, though. I can bring up with the rest of the team as to whether such a filter might be appropriate for in-box inclusion in the product and if any of our other automated behavior should change.
counsellorbe...
Member
540 Points
112 Posts
Re: MVC3 JSON Model binding not working with AntiForgery
Nov 24, 2010 05:37 PM|LINK
Levi,
I may sound as if I am picking at nits, but my original issue (and the original topic of this post) was that the ValidateAntiForgeryToken attribute cannot be used with JSON requests, because the __RequestVerificationToken cannot be passed back in JSON, since the JSON data is not read into the backing store until AFTER the attempt has been made to validate the AntiForgeryToken. As a result, it is not possible to use the ValidateAntiForgeryToken attribute with a JSON request, because the __RequestVerificationToken does not exist when the OnAuthorization event occurs. The out-of-the-box ValidateAntiForgeryToken attribute will always throw a CreateValidationException() on a JSON request.
So it is not that a developer will intentionally remove the ValidateAntiForgeryToken attribute on an Action returning JsonResult, it is that the ValidateAntiForgeryToken attribute will cause the request to fail, so the developer must remove it. By necessity, these Actions are left naked and vulnerable UNLESS the developer ensures the request is XHR. Prior to my insight in the wee small hours of the morning, I would have concluded that my code was secured against a confused deputy attack, since I have the ValidateAntiForgeryToken attribute for all of my Actions returning ActionResults, and everything else (supposedly) operates via XHR.
It was my bone-headed misunderstanding that made me think it was necessary to use the ValidateAntiForgeryToken attribute for this situation, but I was correct in my original assessment of a threat of a confused deputy attack against Actions returning JsonResults. (I may just have injured myself with that pat on the back).
counsellorben
levib
Star
7702 Points
1099 Posts
Microsoft
Re: MVC3 JSON Model binding not working with AntiForgery
Nov 24, 2010 06:09 PM|LINK
Yes, the developer must remove it. The act of removing it should be a huge red flag that manual steps are necessary to secure the application.
Your description makes it sound like it's a vulnerability that the JSON blob doesn't contain the anti-XSRF token. It's not necessary or useful for the JSON blob, XML blob, or any other blob to contain any anti-XSRF token, since by definition those blobs can only come from the same host. The only thing that could come from a different host is the form post body, so that's what we check. It is simply not possible to mount an XSRF attack with XHR.
I think we're narrowing the focus of our discussion, though, and I think we're coming to an agreement. Specifically, your new concern is that the MVC framework makes it too easy to write actions that are meant to be XML-only, JSON-only, etc., but which are in fact more generally callable. Am I understanding your new concern correctly? If so, I agree with these points, and I'll be following up with the rest of the team on how we can make these better.
counsellorbe...
Member
540 Points
112 Posts
Re: MVC3 JSON Model binding not working with AntiForgery
Nov 24, 2010 06:35 PM|LINK
Levi,
Yes, you expressed it very well. It is my concern that actions which the developer expects to be invoked via XHR can be invoked via POST, and therefore are vulnerable to a confused deputy attack.
There seems to be a generalized belief in the developer community that these types of actions are BY THEIR VERY NATURE secured against confused deputy attacks, and no action is necessary. That in fact was the response to my original request, and the original resolution to this post.
You can be certain that some black hats already knew of this attack vector, so it is incumbent upon us (well ... you and the rest of the MVC team, really, since you have the bully pulpit) to do what we (uhh ... you) can to make the developer community aware of this vulnerability. I believe that your earlier suggestion to include some built-in AuthorizationAttribute filters in MVC is an excellent idea, maybe by expanding the JsonRequestAttribute filter I tossed off into a more generalized XhrRequestAttribute filter. I also believe that some code examples to make developers aware of this issue should be disseminated.
Thanks for listening.
counsellorben