Asp.net mvc 3 我应该使用HTTP引用验证或令牌验证来防止CSRF攻击吗?

Asp.net mvc 3 我应该使用HTTP引用验证或令牌验证来防止CSRF攻击吗?,asp.net-mvc-3,security,csrf,Asp.net Mvc 3,Security,Csrf,我在ASP.NET MVC web应用程序中了解了如何保护我的网站免受CSRF攻击。他们提到了两种方法,一种是: 通过使用和[ValidateAntiforgeryToken] 使用HTTP引用方验证,例如: public class IsPostedFromThisSiteAttribute : AuthorizeAttribute { public override void OnAuthorize(AuthorizationContext filterContext)

我在ASP.NET MVC web应用程序中了解了如何保护我的网站免受CSRF攻击。他们提到了两种方法,一种是:

  • 通过使用
    [ValidateAntiforgeryToken]

  • 使用HTTP引用方验证,例如:

    public class IsPostedFromThisSiteAttribute : AuthorizeAttribute
        {
        public override void OnAuthorize(AuthorizationContext filterContext)
            {
            if (filterContext.HttpContext != null)
                {
                if (filterContext.HttpContext.Request.UrlReferrer == null)
                    throw new System.Web.HttpException("Invalid submission");
                if (filterContext.HttpContext.Request.UrlReferrer.Host !=
                    "mysite.com")
                    throw new System.Web.HttpException
                        ("This form wasn't submitted from this site!");
                }
            }
        }
    


  • 因此,我对是否应该使用这两种方法来保护我的网站免受CSRF攻击或是否可以选择其中一种方法感到困惑。HTTP
    Referer
    (原文如此)标题。你不应该依赖它做任何重要的事情。引述:

    “检查HTTP
    Referer
    标头以查看请求是否来自授权页面通常用于嵌入式网络设备,因为它不会增加内存需求。但是,忽略
    Referer
    头的请求必须视为未经授权,因为攻击者可以通过从FTP或HTTPS URL发出请求来抑制
    Referer
    头。这种严格的
    Referer
    验证可能会导致浏览器或代理因隐私原因而忽略
    Referer
    标题。此外,旧版本的Flash(9.0.18之前)允许恶意Flash使用CRLF注入生成具有任意HTTP请求头的GET或POST请求。客户端中类似的CRLF注入漏洞可用于欺骗HTTP请求的引用方。”


    推荐人检查也无助于抵御攻击,攻击者会设法将恶意链接直接注入您的网站。防止此类攻击的唯一可靠方法是使用防伪令牌。

    虽然我从未使用过它,但我个人会避免基于HTTP\U推荐人的任何东西。我认为这现在并不常见,但我记得有一段时间,互联网安全套件(如Norton Internet security)会阻止HTTP_REFERER的发送。这意味着可以阻止真正的用户合法使用您的网站

    编辑:请参阅


    我不认为它是可靠的。

    检查推荐人是有问题的。首先,HTTP规范特别允许客户端不发送推荐人字符串(出于各种隐私原因)。因此,您的一些客户端可能不包括它。其次,可以欺骗推荐人字符串,具有足够技能的攻击者可以使其看起来像成功执行CSRF攻击所需的样子

    使用CSRF验证令牌是一种更强大的方法,也是针对CSRF攻击的首选加密方法。您可以在


    我还将指出,没有理由不能两者兼而有之。深度防御(DiD)策略通常是可取的,因此攻击者需要击败多个独立防御才能成功执行攻击。您可以实施弱引用检查方法(如果客户提供了推荐人,则在按照请求行事之前,确保该推荐人是正确的;如果推荐人不在场,则视其在场且正确进行)与CSRF验证令牌一起使用。这样,如果客户提供了参考信息,您可以检查这些信息,同时仍然使用更强的验证令牌方法。

    正如其他答案所示,仅使用参考者检查是不够的,您确实应该使用防伪令牌

    然而,正如@jeffsix所指出的,您可以使用推荐人检查作为深度防御(DID)策略,因此攻击者需要击败多个独立防御才能执行成功的攻击

    下面的ValidateFerrerattribute属性可用于您的HttpPost MVC操作。如果referer为null,则它不会执行任何操作。如果referer不为null,则它会检查它是否等于指定的主机名。您只需在已经使用ValidateAntiForgeryTokenAttribute的任何位置添加它,这样就很容易添加

    /// <summary>
    /// For POST requests, checks that the requests referrer is the current site. This could be used along side the ValidateAntiForgeryToken
    /// Note that many clients do not send the referrer, so we do nothing in this case.
    /// This attribute can be used as part of a Defence-in-Depth (DID) strategy, so an
    /// attacker would need to defeat multiple, independent, defenses to execute a successful attack.
    /// </summary>
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = false)]
    public class ValidateReferrerAttribute : FilterAttribute, IAuthorizationFilter
    {
        /// <summary>
        /// Called when authorization is required.
        /// </summary>
        /// <param name="filterContext">The filter context.</param>
        /// <exception cref="System.ArgumentNullException">filterContext</exception>
        public void OnAuthorization(AuthorizationContext filterContext)
        {
            if (filterContext == null)
            {
                throw new ArgumentNullException("filterContext");
            }
    
            if ((filterContext.HttpContext.Request.UrlReferrer != null) &&
                string.Equals(filterContext.HttpContext.Request.HttpMethod, "POST", StringComparison.OrdinalIgnoreCase) &&
                !string.Equals(filterContext.HttpContext.Request.UrlReferrer.Host, filterContext.HttpContext.Request.Url.Host, StringComparison.OrdinalIgnoreCase))
            {
                this.HandleExternalPostRequest(filterContext);
            }
        }
    
        /// <summary>
        /// Handles post requests that are made from an external source. 
        /// By default a 403 Forbidden response is returned.
        /// </summary>
        /// <param name="filterContext">The filter context.</param>
        /// <exception cref="System.Web.HttpException">Request not allowed.</exception>
        protected virtual void HandleExternalPostRequest(AuthorizationContext filterContext)
        {
            throw new HttpException((int)HttpStatusCode.Forbidden, "Request not allowed.");
        }
    }
    
    //
    ///对于POST请求,检查请求引用者是否为当前站点。这可以与ValidateAntiForgeryToken一起使用
    ///请注意,许多客户不发送推荐人,因此在这种情况下我们不做任何事情。
    ///此属性可作为纵深防御(DID)策略的一部分,因此
    ///攻击者需要击败多个独立的防御才能成功执行攻击。
    /// 
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class,Inherited=true,AllowMultiple=false)]
    公共类ValidateFerreratAttribute:FilterAttribute,IAAuthorizationFilter
    {
    /// 
    ///需要授权时调用。
    /// 
    ///过滤器上下文。
    ///过滤上下文
    授权时的公共无效(AuthorizationContext filterContext)
    {
    如果(filterContext==null)
    {
    抛出新ArgumentNullException(“filterContext”);
    }
    if((filterContext.HttpContext.Request.UrlReferer!=null)&&
    string.Equals(filterContext.HttpContext.Request.HttpMethod,“POST”,StringComparison.OrdinalIgnoreCase)&&
    !string.Equals(filterContext.HttpContext.Request.UrlReferer.Host,filterContext.HttpContext.Request.Url.Host,StringComparison.OrdinalingOreCase))
    {
    this.HandleExternalPostRequest(filterContext);
    }
    }
    /// 
    ///处理从外部源发出的post请求。
    ///默认情况下,返回403禁止响应。
    /// 
    ///过滤器上下文。
    ///不允许请求。
    受保护的虚拟空句柄ExternalPostRequest(AuthorizationContext filterContext)
    {
    抛出新的HttpException((int)HttpStatusCode.Forbidden,“不允许请求”);
    }
    }
    
    但是,防伪令牌方法真的可以抵御大多数基于CSRFC的攻击吗?但是它不会阻止那些试图自动注册(然后发送垃圾邮件)用户到您站点的机器人。所以
    /// <summary>
    /// For POST requests, checks that the requests referrer is the current site. This could be used along side the ValidateAntiForgeryToken
    /// Note that many clients do not send the referrer, so we do nothing in this case.
    /// This attribute can be used as part of a Defence-in-Depth (DID) strategy, so an
    /// attacker would need to defeat multiple, independent, defenses to execute a successful attack.
    /// </summary>
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = false)]
    public class ValidateReferrerAttribute : FilterAttribute, IAuthorizationFilter
    {
        /// <summary>
        /// Called when authorization is required.
        /// </summary>
        /// <param name="filterContext">The filter context.</param>
        /// <exception cref="System.ArgumentNullException">filterContext</exception>
        public void OnAuthorization(AuthorizationContext filterContext)
        {
            if (filterContext == null)
            {
                throw new ArgumentNullException("filterContext");
            }
    
            if ((filterContext.HttpContext.Request.UrlReferrer != null) &&
                string.Equals(filterContext.HttpContext.Request.HttpMethod, "POST", StringComparison.OrdinalIgnoreCase) &&
                !string.Equals(filterContext.HttpContext.Request.UrlReferrer.Host, filterContext.HttpContext.Request.Url.Host, StringComparison.OrdinalIgnoreCase))
            {
                this.HandleExternalPostRequest(filterContext);
            }
        }
    
        /// <summary>
        /// Handles post requests that are made from an external source. 
        /// By default a 403 Forbidden response is returned.
        /// </summary>
        /// <param name="filterContext">The filter context.</param>
        /// <exception cref="System.Web.HttpException">Request not allowed.</exception>
        protected virtual void HandleExternalPostRequest(AuthorizationContext filterContext)
        {
            throw new HttpException((int)HttpStatusCode.Forbidden, "Request not allowed.");
        }
    }