Должен ли я использовать проверку HTTP-реферера или токена для предотвращения CSRF-атак? - PullRequest
9 голосов
/ 15 февраля 2012

Я читал о том, как защитить свой веб-сайт от CSRF-атак в веб-приложении ASP.NET MVC. Они упомянули два способа сделать это:

  1. с использованием проверки токена с использованием <@Html.AntiForgeryToken()> и [ValidateAntiforgeryToken]

  2. с использованием проверки 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!");
                }
            }
        }
    

    и

    [IsPostedFromThisSite]
    public ActionResult Register(…)
    

Таким образом, я запутался, стоит ли мне использовать оба из них для защиты моего веб-сайта от CSRF-атак или я могу выбрать один из этих методов?

Ответы [ 4 ]

10 голосов
/ 15 февраля 2012

Проверка реферера проблематична.Прежде всего, спецификация HTTP специально позволяет клиентам не отправлять строки реферера (по различным причинам конфиденциальности).Таким образом, некоторые из ваших клиентов могут не включать его.Во-вторых, строки рефералов могут быть подделаны, когда злоумышленник с достаточным навыком может заставить их выглядеть так, как они должны быть для проведения успешной атаки CSRF.

Использование токена проверки CSRF является более сильным подходом иявляется предпочтительным методом смягчения последствий атак CSRF.Вы можете прочитать о том, почему это происходит в OWASP CSRF Шпаргалке .

. Я также укажу, что нет причин, по которым вы не можете сделать оба варианта.Стратегия глубокоэшелонированной защиты (DiD), как правило, желательна, так что злоумышленнику потребуется победить несколько независимых защит для успешной атаки.Вы могли бы реализовать подход проверки слабого реферера (если клиент предоставляет реферер, убедитесь, что он именно такой, каким он должен быть, прежде чем выполнять запрос; если реферер отсутствует, действуйте так, как если бы он присутствовал и был корректным)вместе с маркером проверки CSRF.Таким образом, вы проверяете указанную информацию, если клиент предоставляет ее, все еще используя более сильный подход маркера проверки.

2 голосов
/ 29 апреля 2015

Как указано в других ответах, использование проверок реферера само по себе недостаточно, и вам действительно следует использовать токены против подделки.

Однако, как указал @jeffsix, вы можете использовать проверки реферера в качестве стратегии защиты в глубине (DID), поэтому злоумышленнику потребуется одолеть несколько независимых защит для успешной атаки.

Атрибут ValidateReferrerAttribute, приведенный ниже, можно использовать в действиях HttpPost MVC. Если реферер нулевой, он ничего не делает. Если реферер не равен нулю, он проверяет, что он равен указанному имени хоста. Вам просто нужно добавить его везде, где вы уже используете атрибут 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.");
    }
}
2 голосов
/ 15 февраля 2012

Хотя я никогда не использовал его, лично я бы не стал основывать что-либо на HTTP_REFERER. Я не думаю, что сейчас это обычное дело, но я помню время, когда наборы безопасности Интернета (например, Norton Internet Security) блокировали отправку HTTP_REFERER. Это просто означает, что подлинным пользователям может быть запрещено законное использование вашего сайта.

Редактировать: см. этот вопрос .

Я бы не рассчитывал, что это будет надежно.

2 голосов
/ 15 февраля 2012

Заголовок HTTP Referer (sic) ненадежен .Вы не должны зависеть от этого для чего-то важного.Процитируем статью CSRF Википедии :

"Проверка заголовка HTTP Referer для проверки того, поступает ли запрос с авторизованной страницы, обычно используется для встроенных сетевых устройств, посколькуне увеличивать требования к памяти. Однако запрос, в котором отсутствует заголовок Referer, должен рассматриваться как неавторизованный, поскольку злоумышленник может подавить заголовок Referer, отправляя запросы с URL-адресов FTP или HTTPS. Эта строгая проверка Referer может вызвать проблемы с браузерамиили прокси, которые не содержат заголовок Referer по соображениям конфиденциальности. Кроме того, старые версии Flash (до 9.0.18) позволяют вредоносным Flash генерировать запросы GET или POST с произвольными заголовками HTTP-запросов с помощью инъекции CRLF. Подобные уязвимости внедрения CRLF в клиентеможет использоваться для подделки реферера HTTP-запроса. "

Проверка реферера также не поможет против постоянных CSRF атак, когда злоумышленнику удается внедрить вредоносную ссылку напрямуюна ваш сайт.Единственный надежный способ защиты от таких атак - использовать токены против подделки.

...