JSON POST 的 ASP.Net MVC CSRF 预防

发布于 2024-12-02 18:22:39 字数 482 浏览 2 评论 0原文

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

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

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 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

静待花开 2024-12-09 18:22:39

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

如果请求的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,但更好的防御措施是创建一个属性来验证请求的类型是否为 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;
         }
    }
}

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;
         }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文