asp.net-mvc - 防止 PUT 和删除请求的 CSRF 攻击 ASP.NET Web API

标签 asp.net-mvc security asp.net-web-api csrf

ValidateAntiForgeryToken 是否适用于 PUT 和删除请求,还是仅适用于 ASP.NET Web API 中的 POST 请求?如果不是,确保其安全的最佳方法是什么?

最佳答案

反 CSRF 通常是通过匹配 cookie 和 body 中的 token 来验证非 ajax 调用(如浏览器表单发布)中的请求来完成。

在 ajax 调用中,建议将 token 放入自定义 header 中。如果您安装了最新的ASP.NET 2012.2 update 。它在 MVC 项目对话框中有一个 spa 模板,演示了如何在 SPA 应用程序中防止 CSRF。以下是从模板复制的代码,用于从服务器端验证 header token 。

public class ValidateHttpAntiForgeryTokenAttribute : AuthorizationFilterAttribute
{
    public override void OnAuthorization(HttpActionContext actionContext)
    {
        HttpRequestMessage request = actionContext.ControllerContext.Request;

        try
        {
            if (IsAjaxRequest(request))
            {
                ValidateRequestHeader(request);
            }
            else
            {
                AntiForgery.Validate();
            }
        }
        catch (HttpAntiForgeryException e)
        {
            actionContext.Response = request.CreateErrorResponse(HttpStatusCode.Forbidden, e);
        }
    }

    private bool IsAjaxRequest(HttpRequestMessage request)
    {
        IEnumerable<string> xRequestedWithHeaders;
        if (request.Headers.TryGetValues("X-Requested-With", out xRequestedWithHeaders))
        {
            string headerValue = xRequestedWithHeaders.FirstOrDefault();
            if (!String.IsNullOrEmpty(headerValue))
            {
                return String.Equals(headerValue, "XMLHttpRequest", StringComparison.OrdinalIgnoreCase);
            }
        }

        return false;
    }

    private void ValidateRequestHeader(HttpRequestMessage request)
    {
        string cookieToken = String.Empty;
        string formToken = String.Empty;

        IEnumerable<string> tokenHeaders;
        if (request.Headers.TryGetValues("RequestVerificationToken", out tokenHeaders))
        {
            string tokenValue = tokenHeaders.FirstOrDefault();
            if (!String.IsNullOrEmpty(tokenValue))
            {
                string[] tokens = tokenValue.Split(':');
                if (tokens.Length == 2)
                {
                    cookieToken = tokens[0].Trim();
                    formToken = tokens[1].Trim();
                }
            }
        }

        AntiForgery.Validate(cookieToken, formToken);
    }
}

从客户端,您还需要在ajax调用中设置 header 。这是来自 todo.datacontext.js 的代码:

function ajaxRequest(type, url, data, dataType) { // Ajax helper
    var options = {
        dataType: dataType || "json",
        contentType: "application/json",
        cache: false,
        type: type,
        data: data ? data.toJson() : null
    };
    var antiForgeryToken = $("#antiForgeryToken").val();
    if (antiForgeryToken) {
        options.headers = {
            'RequestVerificationToken': antiForgeryToken
        }
    }
    return $.ajax(url, options);
}

关于asp.net-mvc - 防止 PUT 和删除请求的 CSRF 攻击 ASP.NET Web API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16089393/

相关文章:

asp.net-mvc - 部分 View 和 ModelState.AddModelError

asp.net-mvc - ASP.NET BeginForm() 表达式语法

c# - ViewBag 上的 LinQ 排序依据

c# - 检测 SSL 浏览器支持

c# - 将 DateTimeOffset 作为 WebAPI 查询字符串传递

c# - 使用 EPPlus 生成 excel 文件失败

apache-flex - 检查来自 SWF 文件的 HTTPS 流量

c# - 使用 Ninject OWINHost 的 OWIN 自托管应用程序是否需要 system.web?

c# - Web API 中基于 token 的身份验证,无需任何用户界面

security - 图像清理库