Прочитать на английском

Поделиться через


Файлы cookie SameSite и Открытый веб-интерфейс для .NET (OWIN)

Автор: Рик Андерсон (Rick Anderson)

SameSite— это черновик IETF, предназначенный для обеспечения некоторой защиты от атак на межсайтовые подделки (CSRF). Черновик SameSite 2019:

  • По умолчанию обрабатывает файлы cookie SameSite=Lax .
  • Указывает файлы cookie, которые явно утверждают SameSite=None для включения доставки между сайтами, должны быть помечены как Secure.

Lax работает для большинства файлов cookie приложений. Некоторые формы проверки подлинности, такие как OpenID Connect (OIDC) и WS-Federation по умолчанию перенаправления на основе POST. Перенаправление на основе POST активирует SameSite защиту браузера, поэтому SameSite для этих компонентов отключена. Большинство имен входа OAuth не затрагиваются из-за различий в том, как потоки запросов. Все остальные компоненты не задаются SameSite по умолчанию и используют поведение клиентов по умолчанию (старое или новое).

Параметр None вызывает проблемы совместимости с клиентами, реализующими предыдущий стандарт 2016 г . (например, iOS 12). См. статью "Поддержка старых браузеров " в этом документе.

Каждый компонент OWIN, который выдает файлы cookie, должен решить, подходит ли SameSite это.

Сведения о ASP.NET версии 4.x этой статьи см. в разделе "Работа с файлами cookie SameSite" в ASP.NET.

Использование API с SameSite

Microsoft.Owin имеет собственную SameSite реализацию:

  • Это не зависит напрямую от одного в System.Web.
  • SameSite работает на всех версиях, предназначенных для Microsoft.Owin пакетов, .NET 4.5 и более поздних версий.
  • Только компонент SystemWebCookieManager напрямую взаимодействует с классом System.Web HttpCookie.

SystemWebCookieManager зависит от API .NET 4.7.2 System.Web для включения SameSite поддержки и исправлений для изменения поведения.

Причины использования SystemWebCookieManager описаны в проблемах интеграции файлов cookie OWIN и System.Web Response. SystemWebCookieManager рекомендуется при выполнении System.Webв .

В следующем коде задано Laxследующее значениеSameSite:

owinContext.Response.Cookies.Append("My Key", "My Value", new CookieOptions()
{
    SameSite = SameSiteMode.Lax
});

Используйте SameSiteследующие API:

Журнал и изменения

Microsoft.Owin никогда не поддерживал SameSite стандарт 2016 года.

Поддержка черновика SameSite 2019 доступна только в Microsoft.Owin версии 4.1.0 и более поздних версий. Исправления для предыдущих версий отсутствуют.

Проект спецификации SameSite за 2019 год:

  • Не совместим с черновиком 2016 года. Дополнительные сведения см. в разделе "Поддержка старых браузеров " в этом документе.
  • Указывает, что файлы cookie обрабатываются по SameSite=Lax умолчанию.
  • Указывает файлы cookie, которые явно утверждаются SameSite=None для включения доставки между сайтами, должны быть помечены как Secure. None является новой записью, чтобы отказаться.
  • Планируется включить Chrome по умолчанию в феврале 2020 года. Браузеры начали переходить к этому стандарту в 2019 году.
  • Поддерживается исправлениями, выпущенными в статьях базы знаний. Дополнительные сведения см. в статьях базы знаний, поддерживающих SameSite в платформа .NET Framework.

Поддержка старых браузеров

Стандарт 2016 SameSite года подтвердил, что неизвестные значения должны рассматриваться как SameSite=Strict значения. Приложения, доступные из старых браузеров, поддерживающих стандарт 2016 SameSite , могут нарушиться при получении SameSite свойства со значением None. Веб-приложения должны реализовать обнаружение браузеров, если они намерены поддерживать старые браузеры. ASP.NET не реализует обнаружение браузера, так как значения пользовательских агентов являются очень неустойчивыми и часто изменяются. Точка расширения в ICookieManager позволяет подключаться к логике конкретного агента пользователя.

Добавьте Startup.Configurationкод, аналогичный следующему:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.UseOpenIdConnectAuthentication(
             new OpenIdConnectAuthenticationOptions
             {
                 // … Your preexisting options … 
                 CookieManager = new SameSiteCookieManager(
                                     new SystemWebCookieManager())
             });

        // Remaining code removed for brevity.

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

В следующем коде показан пример реализации SameSiteCookieManager:

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 (options.SameSite == Microsoft.Owin.SameSiteMode.None 
                             && DisallowsSameSiteNone(context))
        {
            options.SameSite = null;
        }
    }

В предыдущем примере DisallowsSameSiteNone вызывается метод CheckSameSite . DisallowsSameSiteNone — это пользовательский метод, который определяет, не поддерживает SameSite Noneли агент пользователя:

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

В следующем коде показан пример DisallowsSameSiteNone метода:

Предупреждение

Следующий код предназначен только для демонстрации:

  • Его не следует считать полным.
  • Он не поддерживается или не поддерживается.
public static bool DisallowsSameSiteNone(IOwinContext context)
{
    var userAgent = context.Request.Headers["User-Agent"];
    
    if (string.IsNullOrEmpty(userAgent))
    {
        return false;
    }
    
    // Cover all iOS based browsers here. This includes:
    // - Safari on iOS 12 for iPhone, iPod Touch, iPad
    // - WkWebview on iOS 12 for iPhone, iPod Touch, iPad
    // - Chrome on iOS 12 for iPhone, iPod Touch, iPad
    // All of which are broken by SameSite=None, because they use the iOS 
    // networking stack.
    if (userAgent.Contains("CPU iPhone OS 12") ||
        userAgent.Contains("iPad; CPU OS 12"))
    {
        return true;
    }

    // Cover Mac OS X based browsers that use the Mac OS networking stack. 
    // This includes:
    // - Safari on Mac OS X.
    // This does not include:
    // - Chrome on Mac OS X
    // Because they do not use the Mac OS networking stack.
    if (userAgent.Contains("Macintosh; Intel Mac OS X 10_14") &&
        userAgent.Contains("Version/") && userAgent.Contains("Safari"))
    {
        return true;
    }

    // Cover Chrome 50-69, because some versions are broken by SameSite=None, 
    // and none in this range require it.
    // Note: this covers some pre-Chromium Edge versions, 
    // but pre-Chromium Edge does not require SameSite=None.
    if (userAgent.Contains("Chrome/5") || userAgent.Contains("Chrome/6"))
    {
        return true;
    }

    return false;
}

Тестирование приложений для проблем с SameSite

Приложения, взаимодействующие с удаленными сайтами, например с помощью стороннего входа, должны:

Тестирование веб-приложений с помощью клиентской версии, которая может принять участие в новом SameSite поведении. Chrome, Firefox и Chromium Edge имеют новые флаги функций, которые можно использовать для тестирования. После применения SameSite исправлений приложение протестирует его с помощью более старых клиентских версий, особенно Safari. Дополнительные сведения см. в разделе "Поддержка старых браузеров " в этом документе.

Тестирование с помощью Chrome

Chrome 78+ дает вводящие в заблуждение результаты, так как он имеет временное устранение рисков. Временное устранение рисков Chrome 78+ позволяет использовать файлы cookie менее чем за две минуты. Chrome 76 или 77 с соответствующими флагами тестирования обеспечивает более точные результаты. Чтобы проверить новое SameSite поведение, chrome://flags/#same-site-by-default-cookies включено. Более старые версии Chrome (75 и ниже) сообщаются о сбое с новым None параметром. См. статью "Поддержка старых браузеров " в этом документе.

Google не делает более старые версии хрома доступными. Следуйте инструкциям в разделе "Скачать Chromium" , чтобы протестировать старые версии Chrome. Не скачивайте Chrome из ссылок, предоставляемых поиском более старых версий хрома.

Тестирование с помощью Safari

Safari 12 строго реализует предыдущий черновик и завершается ошибкой, когда новое None значение находится в файле cookie. None Не используется код обнаружения браузера, поддерживающий старые браузеры в этом документе. Проверьте имена входа в стиль ОС на основе Safari 12, Safari 13 и WebKit с помощью MSAL или любой используемой библиотеки. Эта проблема зависит от базовой версии ОС. OSX Mojave (10.14) и iOS 12, как известно, имеют проблемы совместимости с новым SameSite поведением. Обновление ОС до OSX Catalina (10.15) или iOS 13 устраняет проблему. В настоящее время Safari не имеет флаг согласия на тестирование нового поведения спецификации.

Тестирование с помощью Firefox

Поддержка Firefox для нового стандарта может быть проверена на версии 68+ путем согласия на about:config странице с флагом network.cookie.sameSite.laxByDefaultфункции. Не было отчетов о проблемах совместимости с более старыми версиями Firefox.

Тестирование с помощью браузера Edge

Edge поддерживает старый SameSite стандарт. У пограничных версий 44 нет известных проблем совместимости с новым стандартом.

Тестирование с помощью Edge (Chromium)

SameSite флаги задаются на edge://flags/#same-site-by-default-cookies странице. Проблемы совместимости не обнаружены с пограничным Chromium.

Тестирование с помощью электрона

Версии Electron включают в себя более старые версии Chromium. Например, версия Electron, используемая Teams, — Chromium 66, которая демонстрирует старое поведение. Необходимо выполнить собственное тестирование совместимости с версией используемого продукта Electron. См . раздел "Поддержка старых браузеров " в следующем разделе.

Дополнительные ресурсы