Работа с файлами cookie SameSite в ASP.NET

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

SameSite — это проект стандарта IETF , предназначенный для обеспечения некоторой защиты от атак с подделкой межсайтовых запросов (CSRF). Первоначально разработанный в 2016 году, проект стандарта был обновлен в 2019 году. Обновленный стандарт не является обратно совместимым с предыдущим стандартом, причем наиболее заметными отличиями являются следующие:

  • Файлы cookie без заголовка SameSite обрабатываются как SameSite=Lax по умолчанию.
  • SameSite=None необходимо использовать, чтобы разрешить использование файлов cookie между сайтами.
  • Файлы cookie, которые утверждают SameSite=None , также должны быть помечены как Secure.
  • Приложения, которые используют <iframe> , могут столкнуться с проблемами с файлами sameSite=Lax cookie или sameSite=Strict , так как <iframe> рассматривается как межсайтовые сценарии.
  • Значение SameSite=None не допускается стандартом 2016 года и приводит к тому, что некоторые реализации обрабатывают такие файлы cookie, как SameSite=Strict. См. раздел Поддержка старых браузеров в этом документе.

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

Каждый компонент ASP.NET, который создает файлы cookie, должен решить, подходит ли SameSite.

См. раздел Известные проблемы с приложениями после установки обновлений .NET SameSite 2019.

Использование SameSite в ASP.NET 4.7.2 и 4.8

.NET 4.7.2 и 4.8 поддерживает проект стандарта 2019 для SameSite с момента выпуска обновлений в декабре 2019 года. Разработчики могут программно управлять значением заголовка SameSite с помощью свойства HttpCookie.SameSite. Если задать SameSite для свойства Strictзначение , Laxили None , эти значения записываются в сети с помощью файла cookie. Значение равно (SameSiteMode)(-1) указывает, что заголовок SameSite не должен быть включен в сеть с файлом cookie. Свойство HttpCookie.Secure или requireSSL в файлах конфигурации можно использовать для пометки файла cookie как Secure или нет.

Новые HttpCookie экземпляры по умолчанию будут использовать и SameSite=(SameSiteMode)(-1)Secure=false. Эти значения по умолчанию можно переопределить в system.web/httpCookies разделе конфигурации, где строка "Unspecified" является понятным синтаксисом только для конфигурации для (SameSiteMode)(-1):

<configuration>
 <system.web>
  <httpCookies sameSite="[Strict|Lax|None|Unspecified]" requireSSL="[true|false]" />
 <system.web>
<configuration>

ASP.Net также выдает четыре собственных файла cookie для этих функций: анонимная проверка подлинности, проверка подлинности с помощью форм, состояние сеанса и управление ролями. Экземплярами этих файлов cookie, полученными во время выполнения, можно управлять с помощью SameSite свойств и , как и Secure любым другим экземпляром HttpCookie. Однако из-за появления лоскутных компонентов стандарта SameSite параметры конфигурации для этих четырех функций файлов cookie являются несогласованными. Ниже приведены соответствующие разделы конфигурации и атрибуты со значениями по умолчанию. Если для компонента нет SameSite атрибута или Secure связанного с ним атрибута, функция будет возвращаться к значениям по умолчанию, настроенным в system.web/httpCookies разделе, описанном выше.

<configuration>
 <system.web>
  <anonymousIdentification cookieRequireSSL="false" /> <!-- No config attribute for SameSite -->
  <authentication>
   <forms cookieSameSite="Lax" requireSSL="false" />
  </authentication>
  <sessionState cookieSameSite="Lax" /> <!-- No config attribute for Secure -->
  <roleManager cookieRequireSSL="false" /> <!-- No config attribute for SameSite -->
 <system.web>
<configuration>

Примечание. "Не указано" доступно system.web/httpCookies@sameSite только в данный момент. Мы надеемся добавить аналогичный синтаксис к ранее показанным атрибутам cookieSameSite в будущих обновлениях. Настройка (SameSiteMode)(-1) в коде по-прежнему работает с экземплярами этих файлов cookie.*

Если вы читаете это на языке, отличном от английского, сообщите нам об этом в этой проблеме обсуждения на GitHub , если вы хотите видеть комментарии к коду на вашем родном языке.

Изменение целевой платформы приложений .NET

Для .NET 4.7.2 или более поздней версии:

  • Убедитесь , чтоweb.config содержит следующее:

    <system.web>
      <compilation targetFramework="4.7.2"/>
      <httpRuntime targetFramework="4.7.2"/>
    </system.web>
    
    
  • Убедитесь, что файл проекта содержит правильную версию TargetFrameworkVersion:

    <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
    

    Дополнительные сведения см . в руководстве по миграции .NET .

  • Убедитесь, что пакеты NuGet в проекте предназначены для правильной версии платформы. Вы можете проверить правильную версию платформы, изучив файлpackages.config , например:

    <?xml version="1.0" encoding="utf-8"?>
    <packages>
      <package id="Microsoft.AspNet.Mvc" version="5.2.7" targetFramework="net472" />
      <package id="Microsoft.ApplicationInsights" version="2.4.0" targetFramework="net451" />
    </packages>
    

    В предыдущем файле Microsoft.ApplicationInsightspackages.configпакет:

    • Предназначен для .NET 4.5.1.
    • targetFramework Атрибут должен быть обновлен на , net472 если существует обновленный пакет, предназначенный для целевой платформы.

Версии .NET, предшествующие 4.7.2

Корпорация Майкрософт не поддерживает версии .NET ниже 4.7.2 для записи атрибута файла cookie того же сайта. Мы не нашли надежного способа:

  • Убедитесь, что атрибут написан правильно в зависимости от версии браузера.
  • Перехват и настройка файлов cookie проверки подлинности и сеанса в более старых версиях платформы.

Изменения в поведении исправлений за декабрь

Конкретное изменение поведения для платформа .NET Framework заключается в том, SameSite как свойство интерпретирует None значение:

  • Перед исправлением значение означает None :
    • Не выделяйте атрибут вообще.
  • После исправления:
    • Значение означает None "Выпустить атрибут со значением None".
    • Значение SameSite(SameSiteMode)(-1) приводит к тому, что атрибут не создается.

Значение SameSite по умолчанию для файлов cookie проверки подлинности на основе форм и состояния сеанса изменено с None на Lax.

Сводка по влиянию изменений на браузеры

Если установить исправление и выпустить файл cookie с SameSite.Noneпомощью , произойдет одно из двух действий:

  • Chrome версии 80 будет обрабатывать этот файл cookie в соответствии с новой реализацией и не применять те же ограничения сайта для файла cookie.
  • Любой браузер, который не был обновлен для поддержки новой реализации, будет следовать старой реализации. В старой реализации говорится:
    • Если вы видите значение, которое вы не понимаете, проигнорируйте его и переключитесь на строгие ограничения сайта.

Так что либо приложение ломается в Chrome, либо вы ломаете во многих других местах.

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

Поддержка SameSite была впервые реализована в .NET 4.7.2 с использованием проекта стандарта 2016 года.

Обновления от 19 ноября 2019 г. для Windows обновили .NET 4.7.2+ со стандарта 2016 до стандарта 2019 года. Ожидается выпуск дополнительных обновлений для других версий Windows. Дополнительные сведения см. в статьях базы знаний, поддерживающих SameSite в платформа .NET Framework.

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

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

Известные проблемы

Так как проекты спецификаций 2016 и 2019 несовместимы, обновление .NET Framework за ноябрь 2019 г. содержит некоторые изменения, которые могут быть критическими.

  • Файлы cookie состояния сеанса и проверки подлинности с помощью форм теперь записываются в сеть как Lax не указанные.
    • Хотя большинство приложений работают с файлами SameSite=Lax cookie, приложения POST на сайтах или в приложениях iframe , которые используют, могут обнаружить, что файлы cookie авторизации состояния сеанса или форм используются не так, как ожидалось. Чтобы устранить эту проблему, измените cookieSameSite значение в соответствующем разделе конфигурации, как описано ранее.
  • HttpCookies, которые явно заданы SameSite=None в коде или конфигурации, теперь имеют это значение, записанное с помощью файла cookie, тогда как ранее оно было опущено. Это может привести к проблемам со старыми браузерами, которые поддерживают только проект стандарта 2016 года.
    • При нацеливание на браузеры, поддерживающие проект стандарта 2019 года с SameSite=None помощью файлов cookie, не забудьте также отметить их Secure , иначе они могут не распознаться.
    • Чтобы отменить изменения поведение 2016 без записи SameSite=None, используйте параметр aspnet:SupressSameSiteNone=trueприложения . Обратите внимание, что это относится ко всем HttpCookies в приложении.

Сведения о том, как Служба приложений Azure настраивает поведение SameSite в приложениях .NET 4.7.2, см. в разделе Служба приложений Azure — обработка файлов cookie SameSite и исправление платформа .NET Framework 4.7.2.

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

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

Подход Корпорации Майкрософт к устранению проблемы заключается в том, чтобы помочь вам реализовать компоненты обнаружения браузера, чтобы удалить sameSite=None атрибут из файлов cookie, если браузер, как известно, не поддерживает его. Google советовал выдать двойные файлы cookie, один с новым атрибутом, а один без атрибута на всех. Однако мы считаем, что советы Google ограничены. Некоторые браузеры, особенно мобильные браузеры, имеют очень небольшие ограничения на количество файлов cookie, которые может отправлять сайт, или доменное имя. Отправка нескольких файлов cookie, особенно больших файлов cookie, таких как файлы cookie проверки подлинности, может очень быстро достичь ограничения мобильного браузера, что приводит к сбоям приложений, которые трудно диагностировать и исправить. Кроме того, в качестве платформы существует большая экосистема стороннего кода и компонентов, которые не могут быть обновлены для использования двойного cookie-подхода.

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

Эти обнаружения являются наиболее распространенными агентами браузера, которые поддерживают стандарт 2016 и для которых необходимо полностью удалить атрибут. Это не означает полную реализацию:

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

Способ подключения обнаружения зависит от версии .NET и используемой веб-платформы. На сайте вызова HttpCookie можно вызвать следующий код:

private void CheckSameSite(HttpContext httpContext, HttpCookie cookie)
{
    if (cookie.SameSite == SameSiteMode.None)
    {
        var userAgent = httpContext.Request.UserAgent;
        if (BrowserDetection.DisallowsSameSiteNone(userAgent))
        {
            cookie.SameSite = (SameSiteMode)(-1);
        }
    }
}

См. следующие ASP.NET разделах о файлах cookie SameSite 4.7.2:

Обеспечение перенаправления сайта на HTTPS

Для ASP.NET 4.x, WebForms и MVC функция переопределения URL-адресов IIS может использоваться для перенаправления всех запросов на HTTPS. В следующем XML-коде показан пример правила:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="Redirect to https" stopProcessing="true">
          <match url="(.*)"/>
          <conditions>
            <add input="{HTTPS}" pattern="Off"/>
            <add input="{REQUEST_METHOD}" pattern="^get$|^head$" />
          </conditions>
          <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent"/>
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

В локальных установках переопределение URL-адресов IIS — это необязательный компонент, который может потребовать установки.

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

Необходимо протестировать приложение в поддерживаемых браузерах и выполнить сценарии, в которых используются файлы cookie. Сценарии файлов cookie обычно включают в себя

  • Формы входа
  • Внешние механизмы входа, такие как Facebook, Azure AD, OAuth и OIDC
  • Страницы, принимаюющие запросы от других сайтов
  • Страницы в приложении, предназначенные для внедрения в iframes

Следует проверка, что файлы cookie создаются, сохраняются и удаляются правильно в приложении.

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

Тестирование веб-приложений с помощью версии клиента, которая может согласиться на новое поведение 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 по ссылкам, предоставленным при поиске более старых версий chrome.

Начиная с canary версии 80.0.3975.0, временное устранение рисков Lax+POST можно отключить для тестирования с помощью нового флага --enable-features=SameSiteDefaultChecksMethodRigorously , чтобы разрешить тестирование сайтов и служб в конечном конечном состоянии функции, где устранение рисков было удалено. Дополнительные сведения см. в статье Chromium Projects SameSite Обновления

Тестирование с помощью Chrome 80 и более поздних версий

Скачайте версию Chrome, которая поддерживает новый атрибут. На момент написания статьи текущей версией является Chrome 80. Для использования нового поведения в Chrome 80 должен быть включен флаг chrome://flags/#same-site-by-default-cookies . Также следует включить (chrome://flags/#cookies-without-same-site-must-be-secure), чтобы проверить предстоящее поведение файлов cookie, для которых атрибут sameSite не включен. Chrome 80 находится в целевом режиме, чтобы переключиться на обработку файлов cookie без атрибута как SameSite=Lax, хотя и с временным льготным периодом для определенных запросов. Чтобы отключить период отсрочки по времени, можно запустить Chrome 80 с помощью следующего аргумента командной строки:

--enable-features=SameSiteDefaultChecksMethodRigorously

Chrome 80 содержит предупреждающие сообщения в консоли браузера об отсутствии атрибутов sameSite. Используйте клавишу F12, чтобы открыть консоль браузера.

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

Safari 12 строго реализует предыдущий черновик и завершается сбоем, когда новое None значение находится в файле cookie. None избегается с помощью кода обнаружения браузера Поддержка старых браузеров в этом документе. Проверьте имена входа в стиле ОС на основе Safari 12, Safari 13 и WebKit с помощью MSAL, ADAL или другой используемой библиотеки. Эта проблема зависит от базовой версии ОС. 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. Edge версии 44+ не имеет известных проблем совместимости с новым стандартом.

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

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

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

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

Возврат исправлений SameSite

Вы можете отменить изменения обновленное поведение sameSite в платформа .NET Framework приложениях с предыдущим поведением, когда атрибут sameSite не создается для значения None, а отменить изменения файлы cookie проверки подлинности и сеанса, чтобы не выдавать значение. Это следует рассматривать как чрезвычайно временное исправление, так как изменения Chrome нарушит любые внешние запросы POST или проверку подлинности для пользователей, использующих браузеры, которые поддерживают изменения стандарта.

Восстановление поведения .NET 4.7.2

Обновите web.config , включив следующие параметры конфигурации:

<configuration> 
  <appSettings>
    <add key="aspnet:SuppressSameSiteNone" value="true" />
  </appSettings>
 
  <system.web> 
    <authentication> 
      <forms cookieSameSite="None" /> 
    </authentication> 
    <sessionState cookieSameSite="None" /> 
  </system.web> 
</configuration>

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