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

FMM*_*FMM 16 c# asp.net-mvc csrf asp.net-mvc-3

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

我熟悉MVC使用ValidateAntiForgeryTokenAttribute和自动化CSRF预防的机制@Html.AntiForgeryToken(); 但是,如果我理解正确的话,这个机制需要POST与一个做Content-Typeapplication/x-www-form-urlencoded(或类似).有没有在ASP.Net MVC内置的机制,将拒绝CSRFs用于POST与请求Content-Typeapplication/json?如果没有,我是否坚持将防伪措施放入JSON对象本身?您是否可以推荐一种技术来保护来自CSRF漏洞的JSON POST请求,其安全性与ASP.Net MVC中内置的基于表单的方法相同?

cou*_*ben 10

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

如果请求Content-Type为application/json,则CSRF不是问题.这是因为必须通过提交application/json请求XmlHttpRequest,并且作为AntiForgeryToken验证必要部分的cookie不能跨站点传递,但必须遵守同源策略.

但是,恶意用户可能会提交一个请求,通过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,但更好的防线是创建一个Attribute来验证请求是否为类型application/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;
         }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 感谢您的回答,我现在明白为什么MVC团队没有实现这一点.MVC中是否存在将验证Content-Type的属性,还是留给读者的练习?=) (2认同)
  • 我更新了我的答案,包括一个简单的AuthorizeAttribute类 (2认同)
  • 关于Json请求你还需要注意另一个问题,http://bit.ly/jeET7a (2认同)