开发者

ASP.Net MVC CSRF Prevention for JSON POST

开发者 https://www.devze.com 2023-04-01 16:46 出处:网络
I\'d like to close the CSRF vulnerability for posting raw JSON via AJAX. I\'m familiar with MVC\'s mechanism for automating CSRF prevention using the ValidateAntiForgeryTokenAttribute and @Html.AntiF

I'd like to close the CSRF vulnerability for posting raw JSON via AJAX.

I'm familiar with MVC's mechanism for automating CSRF prevention using the ValidateAntiForgeryTokenAttribute and @Html.AntiForgeryToken(); however, if I understand correctly, this mechanism requires that the POST be done with a Content-Type of application/x-www-form-urlencoded (or similar). Is there a built-in mechanism in ASP.Net MVC 开发者_Go百科that will reject CSRFs for POST requests with Content-Type of application/json? If not, am I stuck with putting the anti-forgery into the JSON object itself? Can you recommend a technique for protecting JSON POST requests from CSRF vulnerability with the same level of security as the form-based approach built into ASP.Net MVC?


This question brings up an interesting discussion.

Provided that the request Content-Type is application/json, then CSRF is not a concern. This is because application/json requests must be submitted via XmlHttpRequest, and the cookie which is a necessary part of the verification of your AntiForgeryToken cannot be passed cross-site, but must adhere to the Same Origin Policy.

However, it is possible for a malicious user to submit a request via application/x-www-form-urlencoded which contains the information which will appear to be a valid JSON request, and which will pass any authorization cookies back to your application. There is a more detailed discussion of this at http://forums.asp.net/t/1624454.aspx/1?MVC3+JSON+Model+binding+not+working+with+AntiForgery and at http://aspnet.codeplex.com/workitem/7472, where I post a proof-of-concept.

While it is possible to include the __RequestVerificationToken in a JSON request, a better line of defense is to create an Attribute to verify that a request is of type application/json, since any other request being submitted to your action which expects JSON is in fact invalid, and should not be handled.

I expect that this security issue will be addressed in MVC 4.

UPDATE:

Here is a simple AuthorizeAttribute class you can use to decorate any actions which expect to receive JSON:

public class JsonRequestAttribute : AuthorizeAttribute
{

    /*
     * 
     *   CONFIRM that this is REALLY a JSON request.
     *   This will mitigate the risk of a CSRF attack
     *   which masquerades an "application/x-www-form-urlencoded" request
     *   as a JSON request
     * 
     */

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
         if (!filterContext.HttpContext.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
         {
             // This request is masquerading as a JSON request, kill it.
             JsonResult unauthorizedResult = new JsonResult();
             unauthorizedResult.Data = "Invalid request";
             unauthorizedResult.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
             filterContext.HttpContext.Response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest;
             filterContext.Result = unauthorizedResult;
         }
    }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消