如何使用内容安全策略报告发布防伪令牌

时间:2017-03-15 20:32:26

标签: asp.net asp.net-mvc-5 content-security-policy antiforgerytoken

在我的ASP.NET MVC应用程序中,我实现了自定义AntiForgeryToken属性,该属性验证AntiForgeryToken的每个POST请求。这样我就不必在每个操作方法上添加[ValidateAntiForgeryToken]属性,而是为所有POST请求全局处理。

最近,我为我的网络应用程序启用了内容安全策略。 CSP如下所示

default-src 'none' https:; 
script-src 'self'; 
style-src 'self';
img-src 'self' data:; 
font-src 'self'; 
report-uri /csp/report;

浏览器将违规报告发布到/csp/report网址,但没有防伪令牌,因此我的全局防伪验证失败。

_layout.cshtml页面中,我创建了令牌@Html.AntiForgeryToken()。因此,为每个视图创建了令牌。

当浏览器POST csp-report时,无论如何都告诉浏览器如果在DOM中可用,还会发布防伪标记?

现在只是为了让它正常工作,我更新了我的防伪验证逻辑,以跳过/csp/report/网址的验证。

更新1

public class ValidatePostAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter
{
    private const string _tokenKey = "__RequestVerificationToken";
    public void OnAuthorization(AuthorizationContext filterContext)
    {
        if (filterContext == null)
        {
            throw new ArgumentNullException("filterContext");
        }

        if (filterContext.HttpContext.Request.HttpMethod.ToUpper() == "POST")
        {
            if (filterContext.HttpContext.Request.IsAjaxRequest())
            {                    
                if (filterContext.HttpContext.Request.Cookies.Get(AntiForgeryConfig.CookieName) == null)
                {
                    throw new HttpPostAntiForgeryException("Invalid Verification Cookie.");
                }
                if (filterContext.HttpContext.Request.Headers.Get(_tokenKey) == null)
                {
                    throw new HttpPostAntiForgeryException("Invalid Verification Token.");
                }

                AntiForgery.Validate(filterContext.HttpContext.Request.Cookies[AntiForgeryConfig.CookieName].Value, filterContext.HttpContext.Request.Headers[_tokenKey]);
            }
            else
            {
                // dont validate post for content security policy report
                if (filterContext.HttpContext.Request.Url.AbsolutePath.ToLower().Contains("csp/report"))
                {
                    return;
                }

                // validate non ajax POST
                AntiForgery.Validate();
            }
        }
    }
}

0 个答案:

没有答案