Объяснение SameSiteатрибута файлов cookie
Защитите свой сайт, узнав, как явно отмечать межсайтовые файлы cookie.
Файлы cookieэто один из доступных методов добавления постоянного состояния веб-сайтам. С годами возможности cookie росли и развивались, но платформа сохранила часть прежних проблем. Для их решения браузеры (в том числе Chrome, Firefox и Edge) меняют свое поведение, чтобы обеспечить больше устанавливаемых по умолчанию параметров, сохраняющих конфиденциальность.
Каждый файл cookie представляет собой пару key=value
, дополненную рядом атрибутов, которые определяют, когда и где используется этот файл cookie. Вероятно, вы уже использовали эти атрибуты, чтобы установить дату истечения срока действия или указать, что файл cookie должен отправляться только по HTTPS. Серверы устанавливают файлы cookie, отправляя в своем ответе заголовок Set-Cookie
. Чтобы узнать обо всех подробностях, вы можете погрузиться в RFC6265bis, а пока что краткое напоминание.
Допустим, у вас есть блог, в котором вы хотите показывать своим пользователям рекламу «Что нового». Пользователи могут закрыть рекламу, и не будут видеть ее в течение некоторого времени. Вы можете сохранить это предпочтение в файле cookie, установить для него срок действия в месяц (2600000 секунд) и отправлять файл cooki только по HTTPS. Этот заголовок будет выглядеть так:
Set-Cookie: promo_shown=1; Max-Age=2600000; Secure

Set-Cookie
.Когда ваш читатель просматривает страницу, которая соответствует этим требованиям, то есть просматривается в безопасном соединении, а возраст cookie не превышает одного месяца, браузер пользователя отправит этот заголовок в своем запросе:
Cookie: promo_shown=1

Cookie
.Вы также можете добавлять и читать файлы cookie, доступные для этого сайта, в JavaScript, используя document.cookie
. Запись в document.cookie
приведет к созданию или переопределению файла cookie с этим ключом. Например, в консоли JavaScript браузера можно попробовать выполнить следующее:
→ document.cookie = "promo_shown=1; Max-Age=2600000; Secure"
← "promo_shown=1; Max-Age=2600000; Secure"
При чтении document.cookie
будут выведены все файлы cookie, доступные в текущем контексте, причем каждый файл cookie разделен точкой с запятой:
→ document.cookie;
← "promo_shown=1; color_theme=peachpuff; sidebar_loc=left"

document.cookie
.Если вы попробуете сделать это на нескольких популярных сайтах, вы заметите, что большинство из них устанавливают значительно больше трех файлов cookie. В большинстве случаев эти файлы cookie отправляются при каждом запросе к этому домену, что имеет ряд последствий. Пропускная способность каналов загрузки часто более ограничена, чем каналов скачивания для ваших пользователей, поэтому накладные расходы на все исходящие запросы добавляют задержку к времени до первого байта. Будьте осторожны в выборе количества и размера файлов cookie, которые вы устанавливаете. Используйте атрибут Max-Age
, чтобы гарантировать, что файлы cookie не будут храниться дольше необходимого.
Что такое основные и сторонние файлы cookie? #
Если вы вернетесь к предыдущей подборке сайтов, то, вероятно, заметите, что присутствуют файлы cookie для различных доменов, а не только для того, который вы посещаете в данный момент. Файлы cookie, соответствующие домену текущего сайта, то есть тому, что отображается в адресной строке браузера, называются основными файлами cookie. Аналогично, файлы cookie из доменов, отличных от текущего сайта, называются сторонними файлами cookie. Это определение не абсолютное, а зависит от контекста пользователя; один и тот же файл cookie может быть как основным, так и сторонним, в зависимости от того, на каком сайте пользователь находится в данный момент.

Продолжая приведенный выше пример, предположим, что в одном из ваших сообщений в блоге есть изображение изумительно чудесного котика, и оно размещено по адресу /blog/img/amazing-cat.png
. Поскольку это изображение такое изумительное, другой человек использует его прямо на своем сайте. Если посетитель был в вашем блоге и у него файл cookie promo_shown
, то, когда он просматривает amazing-cat.png
на сайте другого человека, этот файл cookie будет отправлен в этом запросе для изображения. Это никому не нужно, так как promo_shown
ни для чего не используется на сайте этого человека, он просто добавляет накладные расходы к запросу.
Если это непреднамеренный эффект, то зачем вам это нужно? Именно этот механизм позволяет сайтам сохранять состояние, когда они используются в стороннем контексте. Например, если вы разместите на своем сайте видео с YouTube, посетители увидят в проигрывателе опцию «Посмотреть позже». Если ваш посетитель уже зарегистрирован на YouTube, его сессия будет доступна во встроенном проигрывателе с помощью стороннего cookie, то есть кнопка «Посмотреть позже» просто сохранит видео одним махом, а не предложит ему войти в систему или переместит его с вашей страницы обратно на YouTube.

Файл cookie в стороннем контексте отправляется при посещении разных страниц.
Одно из культурных свойств Интернета заключается в том, что он по умолчанию считается открытым. Отчасти это позволило многим людям создавать собственный контент и приложения. Однако это также породило ряд проблем, связанных с безопасностью и конфиденциальностью. Атаки с подделкой межсайтовых запросов (CSRF) основываются на том факте, что файлы cookie прикрепляются к любому запросу из заданного источника, независимо от того, кто инициирует запрос. Например, если вы посетите evil.example
, он может инициировать запросы к your-blog.example
, и ваш браузер с радостью прикрепит связанные файлы cookie. Если ваш блог не будет внимательно следить за тем, как он проверяет эти запросы, то evil.example
может инициировать такие действия, как удаление сообщений или добавление собственного контента.
Пользователи также становятся более осведомленными о том, как файлы cookie могут использоваться для отслеживания их активности на нескольких сайтах. Однако до сих пор не существовало способа явно заявить о своих намерениях в отношении файла cookie. Ваш файл cookiepromo_shown
должен отправляться только как основной, тогда как сессионный cookie для виджета, предназначенного для встраивания на другие сайты, намеренно предназначен для обеспечения состояния входа в систему в контексте третьей стороны.
Явно укажите использование файлов cookie с помощью атрибута SameSite
#
Введение атрибута SameSite
(определенного в RFC6265bis) позволяет вам объявить, должен ли ваш файл cookie быть основным или внутрисайтовым. На этом моменте давайте вспомним, что именно означает «сайт». Сайтэто комбинация суффикса домена и части домена непосредственно перед ним. Например, домен www.web.dev
является частью сайта web.dev
.
Список публичных суффиксов public suffix list определяет это, поэтому речь не только о доменах верхнего уровня, таких как .com
, но и о сервисах, таких как github.io
, что позволяет считать your-project.github.io
и my-project.github.io
отдельными сайтами.
Введение атрибута SameSite
в файл cookie предоставляет три различных способа управления этим поведением. Вы можете не указывать атрибут или использовать значения атрибута Strict
или Lax
, чтобы ограничить файлы cookie внутрисайтовыми запросами.
Если вы установите для атрибута SameSite
значение Strict
, ваш файл cookie будет отправляться только для внутрисайтовых запросов. Говоря языком пользователей, файл cookie будет отправлен только в том случае, если сайт для файла cookie совпадает с сайтом, который в данный момент отображается в адресной строке браузера. То есть, если файл cookie promo_shown
задан следующим образом:
Set-Cookie: promo_shown=1; SameSite=Strict
Когда пользователь находится на вашем сайте, файл cookie будет отправлен вместе с запросом, как и ожидалось. Однако при переходе по ссылке на ваш сайт, например, с другого сайта или по электронной почте от друга, при первом запросе файл cookie не будет отправлен. Это хорошо, если файлы cookie относятся к функциям, стоящим за начальной навигацией, например, сменой пароля или совершением покупки, но слишком ограничивает promo_shown
. Если ваш пользователь переходит по ссылке на сайт, он хочет, чтобы файл cookie был отправлен, чтобы были применены пользовательские предпочтения.
Именно здесь и приходит на помощь SameSite=Lax
, который разрешает доступ к навигации верхнего уровня. Давайте вернемся к приведенному выше примеру статьи о котике, где другой сайт ссылается на ваш контент. Они используют непосредственно вашу фотографию котика и дают ссылку на вашу оригинальную статью.
<p>Look at this amazing cat!</p>
<img src="https://blog.example/blog/img/amazing-cat.png" />
<p>Read the <a href="https://blog.example/blog/cat.html">article</a>.</p>
И файл cookie был задан следующим образом:
Set-Cookie: promo_shown=1; SameSite=Lax
Когда читатель находится в блоге другого человека, файл cookie не будет отправлен, если браузер запросит amazing-cat.png
. Однако когда читатель перейдет по ссылке на cat.html
в вашем блоге, этот запрос будет включать файл cookie. Это делает значение Lax
хорошим выбором для файлов cookie, влияющих на отображение сайта, а значение Strict
полезным для файлов cookie, связанных с действиями пользователя.
Наконец, можно не указывать значение, что ранее было способом неявного заявления о том, что вы хотите, чтобы файлы cookie отправлялись во всех контекстах. В последнем проекте RFC6265bis это делается явным образом путем введения нового значения SameSite=None
. Это означает, что вы можете использовать значение None
, чтобы четко указать, что вы намеренно хотите, чтобы файл cookie был отправлен в стороннем контексте.

None
, Lax
или Strict
.Изменения поведения по умолчанию без атрибута SameSite #
Хотя атрибут SameSite
широко поддерживается, он, к сожалению, не получил широкого распространения среди разработчиков. Открытая по умолчанию отправка файлов cookies повсюду означает, что все варианты использования работают, но оставляют пользователя уязвимым для CSRF-атак и непреднамеренной утечки информации. Чтобы побудить разработчиков заявить о своих намерениях и предоставить пользователям более безопасный опыт, в проект IETF (Incrementally Better Cookies) внесены два ключевых изменения:
- если у файлов cookie не задан атрибут
SameSite
, будет считаться, чтоSameSite=Lax
; - для файлов cookie с
SameSite=None
также нужно указывать параметрSecure
, что означает, что такой запрос должен приходить только по защищённому каналу.
Chrome реализует это поведение по умолчанию, начиная с версии 84. В Firefox эти ключевые изменения доступны для тестирования, начиная с Firefox 69, и в будущем они будут использоваться по умолчанию. Чтобы проверить это поведение в Firefox, откройте about:config
и установите network.cookie.sameSite.laxByDefault
. Edge также планирует изменить свое поведение по умолчанию.
SameSite=Lax
по умолчанию #
No attribute set
Set-Cookie: promo_shown=1
Если вы отправляете файл cookie без заданного значения для атрибута SameSite
…
Default behavior applied
Set-Cookie: promo_shown=1; SameSite=Lax
Браузер будет обрабатывать этот файл cookie, как если бы было указано SameSite=Lax
.
Хотя это и задумывалось для применения более безопасного значения по умолчанию, в идеале вам следует явно задать значение атрибута SameSite
, а не полагаться на то, что браузер применит его за вас. Это делает ваше намерение в отношении файлов cookie явным и повышает шансы на согласованное использование в разных браузерах.
SameSite=None
должен быть безопасным #
Rejected
Set-Cookie: widget_session=abc123; SameSite=None
Установка cookie без Secure
будет отклонена.
Accepted
Set-Cookie: widget_session=abc123; SameSite=None; Secure
Вы должны убедиться, что для значения атрибута SameSite=None
задан параметр Secure
.
Вы можете протестировать это поведение в Chrome 76, включив about://flags/#cookies-without-same-site-must-be-secure
и в Firefox 69, установив в about:config
настройку network.cookie.sameSite.noneRequiresSecure
.
Уверены, вы захотите применить эту настройку для новых файлов cookie и обновить существующие файлы cookie, даже если срок их действия еще не истек.
Оба эти изменения обратно совместимы с браузерами, которые правильно реализовали предыдущую версию SameSite
или просто не поддерживают его. Применяя эти изменения к своим файлам cookie, вы явно указываете на их предполагаемое использование, а не полагаетесь на поведение браузера по умолчанию. Точно так же любые клиенты, которые еще не распознают SameSite=None
должны игнорировать его и продолжать работу, как если бы атрибут не был установлен.
Рецепты cookie SameSite #
Чтобы прочитать подробнее о том, как именно обновить файлы cookie для успешной обработки изменений SameSite=None
и о различиях в поведении браузеров, перейдите к следующей статье, Рецепты cookie SameSite.
Благодарим за вклад и отзывы Лили Чен, Мальте Убл, Майка Уэста, Роба Додсона, Тома Штайнера и Вивека Сехара.
Главное изображения печенья от Пилле-Рийн Приске на Unsplash