SameSite и Chrome 80: почему в 2020 году начали ломаться куки

Сегодня 12 февраля 2020 года. Chrome 80 вышел в стабильный канал 4 февраля, а включение новых правил для cookies идёт постепенно и должно начаться для ограниченной части пользователей на неделе 17 февраля. Вокруг этого уже начинается вполне ожидаемая паника: «у нас теперь всё сломается». Не всё. Но некоторые вещи действительно лучше проверить сейчас, а не после первого сообщения от клиента «почему кнопка входа ничего не делает».

Коротко: при включении новых правил Chrome будет иначе обрабатывать cookies, у которых не указан атрибут SameSite. Такие cookies будут трактоваться как SameSite=Lax, то есть браузер не станет свободно отправлять их в стороннем контексте. Cookies, которым всё-таки нужен cross-site доступ, должны явно получить SameSite=None; Secure.

Что такое SameSite

Cookie можно отправлять в разных ситуациях: когда пользователь ходит по вашему сайту, когда ваш сайт открыт внутри iframe, когда внешний сервис подгружает картинку или скрипт, когда пользователь переходит с одного домена на другой. Атрибут SameSite говорит браузеру, в каких из этих случаев cookie разрешена.

  • Strict – только в same-site сценариях. Жёстко, иногда слишком жёстко для обычного входа по ссылке из письма.
  • Lax – более мягкий вариант. Cookie доступна при обычной навигации на сайт, но не отправляется в большинстве сторонних запросов.
  • None – cookie разрешена и в cross-site сценариях. Но вместе с ней обязательно нужен Secure, то есть работа по HTTPS.

До этого многие разработчики просто не указывали SameSite и полагались на старое поведение браузеров. В Chrome 80 это перестаёт быть безопасным «авось». Отсутствующий атрибут становится фактически Lax.

Что может перестать работать

Обычная авторизация на одном домене чаще всего не пострадает. А вот проверять нужно всё, где участвуют разные сайты или iframe:

  • федеративный вход и SSO, особенно если авторизация возвращает пользователя POST-запросом;
  • платёжные формы и callback от платёжного сервиса;
  • встроенные кабинеты, виджеты, чаты и формы;
  • рекламные и аналитические интеграции;
  • корзины и личные кабинеты, если фронтенд и API живут на разных доменах.

Самый неприятный вариант – когда всё работает при первом тесте, а потом ломается после паузы. В Chrome 80 существовал временный переходный механизм для некоторых cross-site POST-запросов с недавно созданной cookie. Поэтому тестировать надо не только «нажал сразу», но и после нормального пользовательского сценария с паузой.

Как должны выглядеть cookies

Для обычной сессионной cookie, которая нужна только вашему сайту, можно явно указать безопасное поведение:

Set-Cookie: session=abc123; Path=/; HttpOnly; Secure; SameSite=Lax

Для cookie, которая действительно должна ходить между сайтами, требуется другой вариант:

Set-Cookie: widget=abc123; Path=/; Secure; SameSite=None

Второй пример без HTTPS не спасёт. Chrome потребует Secure, а браузер не должен отправлять такую cookie по обычному HTTP. Это хороший повод проверить, не осталось ли в цепочке авторизации старого HTTP-адреса или тестового поддомена без сертификата.

Что сделать владельцу сайта

  1. Открыть сайт в Chrome 80 и проверить консоль разработчика. Браузер предупреждает о cookies, которые скоро будут заблокированы.
  2. Посмотреть cookies в DevTools, раздел Application, и выписать домен, назначение и атрибуты каждой подозрительной cookie.
  3. Отдельно пройти вход, выход, восстановление пароля, оплату, отправку формы и работу iframe.
  4. Проверить сценарии с несколькими доменами и поддоменами. «У нас всё на одном сервере» не означает «у нас один сайт» с точки зрения браузера.
  5. Обновить плагины и внешние сервисы, которые выставляют cookies. Иногда исправление находится не в вашем PHP, а у поставщика виджета.

Не нужно бездумно ставить SameSite=None на все cookies. Это не универсальная кнопка «чтобы не ломалось», а разрешение на cross-site отправку. Для внутренней сессии лучше выбрать Lax или Strict, если бизнес-сценарий это позволяет.

Про HTTPS, обновления и резервные копии я отдельно писал в материале о скучных вещах, которые спасают выходные. SameSite хорошо ложится в ту же категорию.

Итог

Chrome 80 не запрещает cookies. Он заставляет точнее сказать браузеру, где cookie должна работать. Если cookie нужна только вашему сайту, задайте ей подходящий same-site режим. Если она нужна во внешнем контексте, используйте SameSite=None; Secure и HTTPS.

Проверить это сейчас дешевле, чем объяснять пользователю, почему его личный кабинет исчез после обновления браузера. А если всё-таки что-то перестало работать, начинать поиск стоит с атрибутов Set-Cookie и цепочки редиректов, а не с ритуального «почистите кэш».

Источники