Рецепты печенья SameSite

Chrome , Firefox , Edge и другие изменят поведение по умолчанию в соответствии с предложением IETF «Incrementally Better Cookies», чтобы:

  • Файлы cookie без атрибута SameSite будут обрабатываться как SameSite=Lax , что означает, что по умолчанию файлы cookie будут ограничиваться только собственными контекстами.
  • В файлах cookie для межсайтового использования должно быть указано SameSite=None; Secure , чтобы включить включение в сторонний контекст.

Эта функция является поведением по умолчанию, начиная со стабильной версии Chrome 84 . Если вы еще этого не сделали, вам следует обновить атрибуты сторонних файлов cookie, чтобы они не блокировались в будущем.

Кроссбраузерная поддержка

См. раздел «Совместимость браузера» на странице Set-Cookie MDN.

Варианты использования межсайтовых или сторонних файлов cookie

Существует ряд распространенных случаев и шаблонов использования, когда файлы cookie необходимо отправлять в стороннем контексте. Если вы предоставляете один из этих вариантов использования или зависите от него, убедитесь, что вы или поставщик обновляете свои файлы cookie, чтобы обеспечить правильную работу службы.

Содержимое внутри <iframe>

Содержимое другого сайта, отображаемое в <iframe> , находится в стороннем контексте. Стандартные варианты использования:

  • Встроенный контент, опубликованный с других сайтов, например видео, карты, примеры кода и публикации в социальных сетях.
  • Виджеты внешних сервисов, таких как платежи, календари, функции бронирования и резервирования.
  • Виджеты, такие как кнопки социальных сетей или службы борьбы с мошенничеством, которые создают менее очевидные <iframes> .

Файлы cookie могут использоваться здесь, среди прочего, для поддержания состояния сеанса, хранения общих настроек, включения статистики или персонализации контента для пользователей с существующими учетными записями.

Схема окна браузера, в котором URL-адрес встроенного контента не соответствует URL-адресу страницы.
Если внедренный контент не принадлежит тому же сайту, что и контекст просмотра верхнего уровня, это сторонний контент.

Кроме того, поскольку Интернет по своей сути компонуемый, <iframes> используются для встраивания контента, который также просматривается в контексте верхнего уровня или в собственном контексте. Любые файлы cookie, используемые этим сайтом, будут считаться сторонними файлами cookie, когда сайт отображается в фрейме. Если вы создаете сайты, которые, как вы хотите, легко встраивают другие, а также полагаются на файлы cookie для функционирования, вам также необходимо убедиться, что они помечены для межсайтового использования или что вы можете корректно отказаться от них.

«Небезопасные» запросы на разных сайтах

Хотя слово «небезопасно» здесь может показаться несколько тревожным, оно относится к любому запросу, который может быть предназначен для изменения состояния. В Интернете это в основном POST-запросы. Файлы cookie, отмеченные как SameSite=Lax будут отправляться при безопасной навигации верхнего уровня, например при нажатии ссылки для перехода на другой сайт. Однако что-то вроде отправки <form> через POST на другой сайт не будет включать файлы cookie.

Схема перехода запроса с одной страницы на другую.
Если входящий запрос использует «безопасный» метод, файлы cookie будут отправлены.

Этот шаблон используется для сайтов, которые могут перенаправить пользователя на удаленную службу для выполнения некоторой операции перед возвратом, например перенаправления к стороннему поставщику удостоверений. Прежде чем пользователь покинет сайт, устанавливается файл cookie, содержащий одноразовый токен использования, с ожиданием, что этот токен можно будет проверить в возвращающемся запросе, чтобы смягчить атаки подделки межсайтовых запросов (CSRF) . Если этот возвратный запрос поступает через POST, тогда необходимо будет пометить файлы cookie как SameSite=None; Secure .

Удаленные ресурсы

Любой удаленный ресурс на странице может использовать файлы cookie, отправляемые вместе с запросом из тегов <img> , тегов <script> и т. д. Общие случаи использования включают отслеживание пикселей и персонализацию контента.

Это также относится к запросам, инициированным из вашего JavaScript с помощью fetch или XMLHttpRequest . Если fetch() вызывается с опцией credentials: 'include' это хороший признак того, что в этих запросах вполне могут ожидаться файлы cookie. Для XMLHttpRequest вам следует искать экземпляры свойства withCredentials , для которого установлено значение true . Это хороший признак того, что по этим запросам вполне можно ожидать использования файлов cookie. Эти файлы cookie должны быть соответствующим образом помечены для включения в межсайтовые запросы.

Содержимое внутри WebView

WebView в приложении для конкретной платформы работает на основе браузера, и вам нужно будет проверить, применяются ли те же ограничения или проблемы. В Android, если WebView работает на Chrome, новые значения по умолчанию не будут немедленно применены в Chrome 84. Однако предполагается применить их в будущем, поэтому вам все равно следует протестировать и подготовиться к этому. Кроме того, Android позволяет своим приложениям для конкретной платформы устанавливать файлы cookie непосредственно через API CookieManager . Как и в случае с файлами cookie, установленными через заголовки или JavaScript, рассмотрите возможность включения SameSite=None; Secure , если они предназначены для межсайтового использования.

Как внедрить SameSite сегодня

Для файлов cookie, которым они необходимы только в собственном контексте, в идеале вам следует пометить их как SameSite=Lax или SameSite=Strict в зависимости от ваших потребностей. Вы также можете ничего не делать и просто позволить браузеру применять настройки по умолчанию, но это сопряжено с риском несогласованного поведения в разных браузерах и возможными предупреждениями консоли для каждого файла cookie.

Set-Cookie: first_party_var=value; SameSite=Lax

Для файлов cookie, необходимых в стороннем контексте, вам необходимо убедиться, что они помечены как SameSite=None; Secure . Обратите внимание, что вам нужны оба атрибута вместе. Если вы просто укажете None без Secure », файл cookie будет отклонен. Однако в реализациях браузеров существуют некоторые взаимно несовместимые различия, поэтому вам может потребоваться использовать некоторые стратегии смягчения последствий, описанные в разделе «Обработка несовместимых клиентов» ниже.

Set-Cookie: third_party_var=value; SameSite=None; Secure

Работа с несовместимыми клиентами

Поскольку эти изменения, включающие None и обновление поведения по умолчанию, все еще относительно новы, среди браузеров существуют разногласия относительно того, как эти изменения обрабатываются. Вы можете обратиться к странице обновлений на chromium.org, чтобы узнать об известных на данный момент проблемах, однако невозможно сказать, является ли эта информация исчерпывающей. Хотя это не идеальный вариант, существуют обходные пути, которые вы можете использовать на этом переходном этапе. Однако общее правило состоит в том, чтобы рассматривать несовместимых клиентов как особый случай. Не создавайте исключений для браузеров, реализующих новые правила.

Первый вариант — установить файлы cookie как нового, так и старого стиля:

Set-cookie: 3pcookie=value; SameSite=None; Secure
Set-cookie: 3pcookie-legacy=value; Secure

Браузеры, реализующие новое поведение, будут устанавливать в файле cookie значение SameSite , в то время как другие браузеры могут его игнорировать или устанавливать неправильно. Однако те же самые браузеры будут устанавливать файлы cookie 3pcookie-legacy . При обработке включенных файлов cookie сайт должен сначала проверить наличие файла cookie нового стиля, а если он не найден, то вернуться к устаревшему файлу cookie.

В приведенном ниже примере показано, как это сделать в Node.js, используя платформу Express и ее промежуточное программное обеспечение для анализа файлов cookie .

const express = require('express');
const cp = require('cookie-parser');
const app = express();
app.use(cp());

app.get('/set', (req, res) => {
  // Set the new style cookie
  res.cookie('3pcookie', 'value', { sameSite: 'none', secure: true });
  // And set the same value in the legacy cookie
  res.cookie('3pcookie-legacy', 'value', { secure: true });
  res.end();
});

app.get('/', (req, res) => {
  let cookieVal = null;

  if (req.cookies['3pcookie']) {
    // check the new style cookie first
    cookieVal = req.cookies['3pcookie'];
  } else if (req.cookies['3pcookie-legacy']) {
    // otherwise fall back to the legacy cookie
    cookieVal = req.cookies['3pcookie-legacy'];
  }

  res.end();
});

app.listen(process.env.PORT);

Обратной стороной является то, что это предполагает установку избыточных файлов cookie для всех браузеров и требует внесения изменений как на этапе установки, так и на этапе чтения файла cookie. Однако этот подход должен охватывать все браузеры независимо от их поведения и гарантировать, что сторонние файлы cookie продолжат работать в прежнем режиме.

В качестве альтернативы в момент отправки заголовка Set-Cookie вы можете выбрать обнаружение клиента через строку пользовательского агента. Ознакомьтесь со списком несовместимых клиентов , а затем используйте соответствующую библиотеку для вашей платформы, например библиотеку ua-parser-js на Node.js. Желательно найти библиотеку для обнаружения пользовательских агентов, поскольку вы, скорее всего, не захотите писать эти регулярные выражения самостоятельно.

Преимущество этого подхода заключается в том, что он требует внесения только одного изменения в момент установки файла cookie. Однако необходимым предупреждением здесь является то, что анализ пользовательских агентов по своей сути ненадежен и может не выявить всех затронутых пользователей.

Поддержка SameSite=None в языках, библиотеках и платформах.

Большинство языков и библиотек поддерживают атрибут SameSite для файлов cookie, однако добавление SameSite=None все еще является относительно новым, что означает, что вам, возможно, придется пока поработать над некоторыми стандартными функциями. Они описаны в репозитории примеров SameSite на GitHub .

Получать помощь

Файлы cookie встречаются повсюду, и редко какой-либо сайт полностью проверяет, где они установлены и используются, особенно если вы добавляете к ним варианты межсайтового использования. Если вы столкнулись с проблемой, возможно, это первый раз, когда кто-то столкнулся с ней, поэтому не стесняйтесь обращаться к нам: