company_banner

Приближающиеся изменения SameSite Cookie в ASP.NET и ASP.NET Core

Автор оригинала: Microsoft
  • Перевод
SameSite — это расширение файлов cookie HTTP 2016 года, предназначенное для предотвращения подделки межсайтовых запросов (CSRF). Первоначально его дизайн представлял из себя дополнительную функцию, которую можно использовать, добавив новое свойство SameSite в файлы cookie. У него было два значения, Lax и Strict.

При установке значения Lax подразумевается, что куки должны отправляться при серфинге по одному сайту или через GET серфинг на ваш сайт с других сайтов. Значение Strict ограничивало cookie запросами, исходящими только от одного сайта. Отсутствие установки какого-либо свойства не накладывает никаких ограничений на то, как cookie может работать в запросах. Операции аутентификации OpenIdConnect (например, вход в систему, выход из системы) и другие функции, которые отправляют POST-запросы с внешнего сайта на сайт, запрашивающий операцию, могут использовать файлы cookie для корреляции и/или защиты CSRF. Эти операции должны были бы отказаться от SameSite, не устанавливая свойство вообще, чтобы гарантировать, что эти куки будут отправлены во время их специализированных потоков запросов (specialized request flows).

Сейчас Google обновляет стандарт и внедряет предложенные изменения в будущую версию Chrome. Изменение добавляет новое значение SameSite «None» и изменяет поведение по умолчанию на «Lax». Это ломает OpenIdConnect logins и, возможно, другие функции, на которые может опираться ваш веб-сайт. Эти функции должны будут использовать файлы cookie, для свойства SameSite которых установлено значение «None».

Однако браузеры, которые придерживаются первоначального стандарта и не знают о новом значении, ведут себя иначе, чем браузеры, которые используют новый стандарт. Это означает, что ваш веб-сайт .NET теперь должен будет добавить сниффинг пользовательского агента (user agent sniffing), чтобы решить, отправлять ли вы новое значение None или не отправлять атрибут вообще.



.NET получит обновления, позволяющие изменить поведение атрибута SameSite в .NET 4.7.2 и .NET Core 2.1 и выше, чтобы подстроиться под введение Google нового значения. Обновления для .NET Framework будут доступны 19 ноября в качестве дополнительного обновления через Центр обновления Майкрософт и WSUS, если вы используете функцию «Проверить наличие обновлений». 10 декабря обновление станет общедоступным и появится в Центре обновлений Майкрософт. Обновления .NET Core станут доступны в ноябре с выходом .NET Core 3.1, начиная с Превью 1.

.NET Core 3.1 будет содержать обновленное enum definition, SameSite.Unspecified, которое не будет устанавливать свойство SameSite.

Промежуточное программное обеспечение OpenIdConnect для Microsoft.Owin v4.1 и .NET Core обновится одновременно с обновлениями .NET Framework и .NET, однако мы не можем добавить код user agent sniffing в фреймворк, это должно быть реализовано в коде вашего сайта. Реализация agent sniffing будет зависеть от того, какую версию ASP.NET или ASP.NET Core вы используете и какие браузеры вы хотите поддерживать.

Для ASP.NET 4.7.2 с Microsoft.Owin 4.1.0 agent sniffing может быть реализован с помощью ICookieManager;

public class SameSiteCookieManager : ICookieManager
{
  private readonly ICookieManager _innerManager;

  public SameSiteCookieManager() : this(new CookieManager())
  {
  }

  public SameSiteCookieManager(ICookieManager innerManager)
  {
    _innerManager = innerManager;
  }

  public void AppendResponseCookie(IOwinContext context, string key, string value,
                                   CookieOptions options)
  {
    CheckSameSite(context, options);
    _innerManager.AppendResponseCookie(context, key, value, options);
  }

  public void DeleteCookie(IOwinContext context, string key, CookieOptions options)
  {
    CheckSameSite(context, options);
    _innerManager.DeleteCookie(context, key, options);
  }

  public string GetRequestCookie(IOwinContext context, string key)
  {
    return _innerManager.GetRequestCookie(context, key);
  }

  private void CheckSameSite(IOwinContext context, CookieOptions options)
  {
    if (DisallowsSameSiteNone(context) && options.SameSite == SameSiteMode.None)
    {
        options.SameSite = null;
    }
  }

  public static bool DisallowsSameSiteNone(IOwinContext context)
  {
    // TODO: Используйте выбранную библиотеку User Agent здесь.
    var userAgent = context.Request.Headers["User-Agent"];
    return userAgent.Contains("BrokenUserAgent") ||
           userAgent.Contains("BrokenUserAgent2")
  }
}

А затем настройте параметры OpenIdConnect для использования нового CookieManager;

app.UseOpenIdConnectAuthentication(
    new OpenIdConnectAuthenticationOptions
    {
    // … Ваши предыдущие настройки … 
    CookieManager = new SameSiteCookieManager(new SystemWebCookieManager())
});

Для правильной работы SystemWebCookieManager потребуется установка исправленного SameSite .NET 4.7.2 или более поздней версии.

Для ASP.NET Core вы должны установить исправления, а затем внедрить код agent sniffing в политику cookie. Для версий до 3.1 замените SameSiteMode.Unspecified на (SameSiteMode)(- 1).

private void CheckSameSite(HttpContext httpContext, CookieOptions options)
{
    if (options.SameSite > SameSiteMode.Unspecified)
    {
        var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
        // TODO: Используйте выбранную библиотеку User Agent здесь.
        if (/* UserAgent doesn’t support new behavior */)
        {
               // Для .NET Core < 3.1 установите SameSite = -1
               options.SameSite = SameSiteMode.Unspecified;
         }
    }
}

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
    {
        options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
        options.OnAppendCookie = cookieContext => 
            CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
        options.OnDeleteCookie = cookieContext => 
            CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
    });
}

public void Configure(IApplicationBuilder app)
{
    app.UseCookiePolicy(); // Before UseAuthentication or anything else that writes cookies.
    app.UseAuthentication();
    // …
}

При тестировании с командой Azure Active Directory мы обнаружили, что следующие проверки работают для всех распространенных user agent, которые, согласно Azure Active Directory, не понимают новое значение.

public static bool DisallowsSameSiteNone(string userAgent)
{
    // Примените это к браузерам для iOS. В том числе:
    // - Safari на iOS 12 для iPhone, iPod Touch, iPad
    // - WkWebview на iOS 12 для iPhone, iPod Touch, iPad
    // - Chrome на iOS 12 для iPhone, iPod Touch, iPad
    if (userAgent.Contains("CPU iPhone OS 12") || userAgent.Contains("iPad; CPU OS 12"))
    {
        return true;
    }

    // Также с браузерами для Mac OS X. В том числе:
    // - Safari на Mac OS X.
    // Не включая:
    // - Chrome на Mac OS X
    // Потому что он не использует сетевой стек Mac OS.
    if (userAgent.Contains("Macintosh; Intel Mac OS X 10_14") && 
        userAgent.Contains("Version/") && userAgent.Contains("Safari"))
    {
        return true;
    }

    // Также примените к Chrome 50-69, потому что некоторые версии ломаются SameSite=None.
    if (userAgent.Contains("Chrome/5") || userAgent.Contains("Chrome/6"))
    {
        return true;
    }

    return false;
}

Этот список браузеров ни в коем случае не является чем-то, на что можно всецело полагаться, и вы должны проверить, что обычные браузеры и другие user agent, поддерживаемые вашей системой, ведут себя должным образом после установки обновления.

Chrome 80 должен перейти на новое поведение в феврале или марте 2020 года. Если вы хотите проверить новое поведение, старые версии Chromium доступны для скачивания.

Если вы не можете обновить версии своего фреймворка к тому времени, когда Chrome включит новое поведение в начале 2020 года, возможно, вы сможете изменить поток OpenIdConnect на поток Code, а не на поток, который используется в ASP.NET и ASP.NET Core. Но это следует рассматривать как временную меру.


Мы настоятельно рекомендуем вам загрузить обновленные версии .NET Framework и .NET Core, когда они станут доступны в ноябре, и приступить к планированию обновления до того, как будут внесены изменения в Chrome.
Microsoft
389,02
Microsoft — мировой лидер в области ПО и ИТ-услуг
Поделиться публикацией

Комментарии 0

Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Самое читаемое