На днях внимательная коллега (спасибо, Лена) зарепортила странный баг — сервер нормально ставил куку в браузере, но обратно она не прилетала. Днём ранее всё работало, теперь же кука выставлялась, но спустя несколько секунд магическим образом пропадала (хотя должна держаться сутки). Воспроизводилось это всего у нескольких человек в команде и только в новом Chrome 80, но у остальных в Chrome точно такой же версии всё было в порядке. В других браузерах всё работало как часы. Мистика. Начали разбираться, и спустя какое-то время в консоли Chrome заметили предупреждение для заголовка ответа, устанавливающего куки:
A cookie associated with a cross-site resource at _your_domain_ was set without the `SameSite` attribute. A future release of Chrome will only deliver cookies with cross-site requests if they are set with `SameSite=None` and `Secure`.
Начали изучать что это такое, и постепенно стало понятно, как ошибка возникла и почему проявлялась не у всех. Поскольку наш сервис должен обрабатывать запросы с разных доменов, то SameSite
— как раз наш случай. Добавили SameSite=None; Secure
, и проблема для нас решилась.
Почему так?
Изначально, по стандарту HTTP, браузер отправлял cookies (или просто куки) при любом запросе на соответствующий им домен. Это открывало возможности для CSRF-атаки, то есть позволяло недобросовестным людям при определённом стечении обстоятельств получить доступ к каким-либо ресурсам под видом ничего не подозревающих добросовестных, просто воспользовавшись их куками.
В 2016 году был введён атрибут SameSite
, позволяющий контролировать, будет ли браузер отправлять cookies, если страница посылает запрос на другой домен. У разработчиков появилась возможность блокировать передачу своих кук, если запрос выполняется с постороннего сайта. Для этого атрибуту SameSite
нужно было явно присвоить значение Strict (cookies передаются только при запросах и переходах с домена, к которому они относятся), или Lax (куки передаются при переходе на сайт с других сайтов по прямой ссылке, но не передаются при других запросах с них, например при AJAX-запросе или загрузке картинок). Отсутствие SameSite
было эквивалентно SameSite=None
, то есть по умолчанию cookies всё так же передавались при любых запросах.
В мае 2019 года разработчики Google Chrome объявили, что будут постепенно менять это поведение и трактовать отсутствие SameSite как SameSite=Lax
(подробнее здесь). То есть — по умолчанию браузер будет блокировать передачу cookies при запросах с текущей страницы на любые другие ресурсы, кроме прямых переходов по ссылке. Разработчики Firefox и Edge объявили, что со временем так же внедрят это изменение в своих браузерах.
Для пользователей такое поведение браузера более безопасно. Разработчикам же сайтов и веб-сервисов нужно иметь ввиду, что если им всё-таки требуется получать свои cookies при запросах с других сайтов, они должны будут явно установить своим кукам атрибуты SameSite=None, Secure
(Secure
— потому что такой запрос вдобавок должен приходить на сервер только по защищённому каналу).
Поскольку нововведение меняет действующий стандарт, и не все сайты смогут адаптироваться быстро, то переход к новому поведению происходит постепенно. Изначально его включили у ограниченного числа бета-пользователей Chrome, и вот теперь постепенно увеличивают их количество. Актуальная информация доступна здесь. Самая свежая запись по ссылке:
Last updated March 9, 2020.
We have begun enforcing the new behavior for Chrome 80 stable, just not for 100% of users. The controlled rollout is to a limited initial population,
То есть, период бета-тестирования позади, и разработчики Chrome начали потихоньку включать новый функционал у обычных пользователей. Что в принципе хорошо, поскольку так действительно безопаснее.
Вернуть старое поведение возможно через настройки: в адресной строке Chrome ввести chrome://flags
, перейти на страницу, найти пункт SameSite be default cookies, и установить ему значение Disabled. Но это подходит больше для тестирования, чем для простых пользователей. Аналогично, если в вашем Chrome 80 пока работает старое поведение, вы можете принудительно включить новый функционал, установив эту же настройку в Enabled.
Поэтому если вашему сайту требуется получать cookies при запросах с разных доменов — будьте готовы к грядущим переменам (а кто уже готов — тот молодец). Всем добра!
Источники:
web.dev/samesite-cookies-explained
www.chromium.org/updates/same-site
www.chromestatus.com/feature/5088147346030592
Автор: Kolobok86