【问题标题】:ASP.Net MVC CSRF Prevention for JSON POSTJSON POST 的 ASP.Net MVC CSRF 预防
【发布时间】:2011-11-08 12:30:23
【问题描述】:

我想关闭通过 AJAX 发布原始 JSON 的 CSRF 漏洞。

我熟悉 MVC 使用 ValidateAntiForgeryTokenAttribute@Html.AntiForgeryToken() 自动预防 CSRF 的机制;但是,如果我理解正确,此机制要求 POST 使用 Content-Typeapplication/x-www-form-urlencoded(或类似)完成。 ASP.Net MVC 中是否有内置机制可以拒绝 POST 请求的 CSRF,其中 Content-Typeapplication/json?如果不是,我是否坚持将防伪放入 JSON 对象本身?您能否推荐一种技术来保护 JSON POST 请求免受 CSRF 漏洞的影响,其安全级别与 ASP.Net MVC 中内置的基于表单的方法相同?

【问题讨论】:

    标签: c# asp.net-mvc asp.net-mvc-3 csrf


    【解决方案1】:

    这个问题引发了一个有趣的讨论。

    如果请求的 Content-Type 是application/json,那么 CSRF 就不是问题了。这是因为 application/json 请求必须通过XmlHttpRequest 提交,并且作为 AntiForgeryToken 验证的必要部分的 cookie 不能跨站传递,但必须遵守Same Origin Policy

    但是,恶意用户可以通过 application/x-www-form-urlencoded 提交请求,其中包含看似有效的 JSON 请求的信息,并且会将任何授权 cookie 传递回你的申请。 http://forums.asp.net/t/1624454.aspx/1?MVC3+JSON+Model+binding+not+working+with+AntiForgeryhttp://aspnet.codeplex.com/workitem/7472 对此进行了更详细的讨论,我在其中发布了概念验证。

    虽然可以在 JSON 请求中包含 __RequestVerificationToken,但更好的防线是创建一个属性来验证请求的类型为 application/json,因为任何其他请求都提交给您的操作,需要 JSON实际上是无效的,不应该处理。

    我希望这个安全问题将在 MVC 4 中得到解决。

    更新:

    这是一个简单的 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;
             }
        }
    }
    

    【讨论】:

    • 感谢您的回答,我现在明白为什么 MVC 团队没有实现这一点。 MVC 中是否有一个属性可以验证 Content-Type,还是留给读者练习? =)
    • 我更新了我的答案以包含一个简单的 AuthorizeAttribute 类
    • 关于 Json 请求还有一个问题需要注意,bit.ly/jeET7a
    • 已确认 - 可以使用 Flash 发出请求,欺骗浏览器发送用户的 cookie 和内容类型为application/json
    • 请注意以application/json 为基础的安全建议。它当时是正确的,但可能很快就不再有效。 W3C 正在制定一个草案,允许表单在其 enctype 属性中使用 application/jsonw3.org/TR/html-json-forms 您确实应该使用 Synrhonizer 令牌模式来适当地防止 CSRF。
    猜你喜欢
    • 1970-01-01
    • 2019-06-09
    • 2015-03-12
    • 2014-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多