SameSite и кроссдоменные cookies
Table of contents
Introduction
Cookies позволяют идентифицировать пользователя и в дальнейшем выполнять запросы от имени данного пользователя.
Поэтому их безопасность очень важна. Ранее для сессионных cookies
уже был добавлен параметр HttpOnly
, который защищает доступ к cookies
из JS
и тем самым препятствует перехвату с помощью XSS
-уязвимостей.
Но все же оставалась возможность сделать запрос с другого домена к сайту (example.com
), на котором авторизован пользователь, с передачей cookies
посредством встраивания скрипта или вызова изображения, например:
<script src="http://example.com">
Для того, чтобы запретить передачу cookies
при таких кроссдоменных запросах, был введен параметр SameSite
, который может принимать следующие значения (первые два запрещают кроссдоменную передачу):
Strict
Lax
None
До недавнего времени браузеры не обрабатывали данный параметр и считали, что он по умолчанию установлен как None
.
Но в феврале Chrome стал обрабатывать параметр SameSite
, и, если параметр не установлен, то значение по умолчанию выставлять Lax
, а не None
, как было до версии 80.
Конечно же, об изменениях было известно заранее (еще в сентябре 2019) и 79 версия Chrome
уже включала в себя поддержку обработки данного параметра, но она по умолчанию была отключена.
С выходом Chrome
80 у некоторых сайтов, которые пользовались возможностью кроссдоменной передачи cookies
, появились проблемы с работоспособностью в данном браузере.
После выхода Chrome
80 было решено на время откатить функционал проверки SameSite
, т.к. не все сайты успели вовремя среагировать на изменения, но позже его опять вернут.
Решения проблемы с SameSite
Для того, чтобы решить данную проблему, необходимо установить для cookies
, которые используются для кроссдоменной передачи, параметр SameSite=None
, но Chrome будет принимать такой параметр только при установке параметра Secure
, т.е., если мы кроссдоменно передаем cookies
, то делать это нужно только по https
.
Для PHP
поддержка параметра SameSite
была введена только в версии 7.3 для функции setcookie
. Для Legacy
-проектов переход на 7.3 версию PHP
может быть затруднителен и поэтому придется выбирать один из обходных путей:
- Использовать вместо
setcookie
обычную установку заголовков через функциюheader
:
header("Set-Cookie: key=value; path=/; domain=example.com; Secure; SameSite=None");
- Воспользоваться классом
Cookie
из пакетаsymfony/http-foundation
: https://github.com/symfony/http-foundation/blob/master/Cookie.php
Описанные выше решения предполагают доработку кода, но установка необходимых cookies
может происходить в коде вендора и поэтому либо придется его форкать, либо отказываться от обновления вендора.
Но если данные методы не подходят, то остается подмена cookies
уже на стороне web
-сервера:
- Для
Apache
необходимо в секцииVirtualHost
добавить подмену:
Header edit Set-Cookie ^((COOKIE_NAME1|COOKIE_NAME2).*)$ "$1;Secure;SameSite=None"
- Для
Nginx
вlocation
добавляем:
proxy_cookie_path / "/; Secure; SameSite=None";
Стоит отметить, что это лишь временные решения и в долгосрочной перспективе необходимо решить проблемы с Legacy
и устанавливать cookies
штатными средствами.
Дата редактирования : 2020-11-12 00:36:06
Автор : Rosko