简体   繁体   English

用于JSON POST的ASP.Net MVC CSRF预防

[英]ASP.Net MVC CSRF Prevention for JSON POST

I'd like to close the CSRF vulnerability for posting raw JSON via AJAX. 我想关闭通过AJAX发布原始JSON的CSRF漏洞。

I'm familiar with MVC's mechanism for automating CSRF prevention using the ValidateAntiForgeryTokenAttribute and @Html.AntiForgeryToken() ; 我熟悉MVC使用ValidateAntiForgeryTokenAttribute@Html.AntiForgeryToken()自动化CSRF预防的机制; 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). 但是,如果我理解正确,这种机制要求POST application/x-www-form-urlencoded Content-Type of application/x-www-form-urlencoded (或类似)。 Is there a built-in mechanism in ASP.Net MVC that will reject CSRFs for POST requests with Content-Type of application/json ? ASP.Net MVC中是否有一个内置机制,它会拒绝使用Content-Type of application/json POST请求的CSRF? If not, am I stuck with putting the anti-forgery into the JSON object itself? 如果没有,我是否坚持将防伪措施放入JSON对象本身? 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? 您是否可以推荐一种技术来保护来自CSRF漏洞的JSON POST请求,其安全性与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. 如果请求Content-Type是application/json ,则CSRF不是问题。 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 . 这是因为必须通过XmlHttpRequest提交application / json请求,并且作为AntiForgeryToken验证必要部分的cookie不能跨站点传递,但必须遵守同源策略

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. 但是,恶意用户可以通过application/x-www-form-urlencoded提交请求,该请求包含看似有效的JSON请求的信息,并将任何授权cookie传递回您的应用程序。 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. http://forums.asp.net/t/1624454.aspx/1?MVC3+JSON+Model+binding+not+working+with+AntiForgeryhttp:// aspnet上有更详细的讨论。 codeplex.com/workitem/7472 ,我发布了一个概念验证。

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. 虽然可以在JSON请求中包含__RequestVerificationToken,但更好的防线是创建一个Attribute来验证请求是否为application/json类型,因为提交给您的操作的任何其他请求实际上都是JSON无效,不应该处理。

I expect that this security issue will be addressed in MVC 4. 我希望这个安全问题将在MVC 4中得到解决。

UPDATE: 更新:

Here is a simple AuthorizeAttribute class you can use to decorate any actions which expect to receive JSON: 这是一个简单的AuthorizeAttribute类,您可以使用它来装饰任何期望接收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;
         }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM