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");

Описанные выше решения предполагают доработку кода, но установка необходимых 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
Автор :

Cookies and IP addresses allow us to deliver and improve our web content, resolve technical errors, and provide you with a personalized experience. Our website uses cookies and collects your IP address for these purposes.