我想关闭通过 AJAX 发布原始 JSON 的 CSRF 漏洞。
我熟悉 MVC 使用 ValidateAntiForgeryTokenAttribute
和 @Html.AntiForgeryToken()
自动预防 CSRF 的机制;但是,如果我理解正确的话,这种机制要求 POST
是使用 application/x-www-form-urlencoded
的 Content-Type
完成的>(或类似)。 ASP.Net MVC 中是否有一种内置机制会拒绝 application/json
的 Content-Type
的 POST
请求的 CSRF?如果不是,我是否坚持将防伪放入 JSON 对象本身?您能否推荐一种技术来保护 JSON POST 请求免受 CSRF 漏洞的攻击,其安全级别与 ASP.Net MVC 中内置的基于表单的方法具有相同的安全级别?
最佳答案
这个问题引发了一个有趣的讨论。
只要请求的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+AntiForgery 中对此有更详细的讨论。在 http://aspnet.codeplex.com/workitem/7472 ,我在其中发布了概念验证。
虽然可以在 JSON 请求中包含 __RequestVerificationToken,但更好的防线是创建一个属性来验证请求的类型为 application/json
,因为任何其他请求都是提交给你的 Action ,它期望 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;
}
}
}
关于c# - JSON POST 的 ASP.Net MVC CSRF 预防,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7272748/