Recettes de cookies SameSite

Chrome, Firefox, Edge, etc., vont modifier leur comportement par défaut conformément à la proposition de l'IETF, Incrémentiellement de meilleures cookies, pour que:

  • Les cookies sans attribut SameSite seront traités comme SameSite=Lax, ce qui signifie que le comportement par défaut consistera à limiter les cookies aux contextes propriétaires uniquement.
  • Les cookies pour une utilisation intersite doivent spécifier SameSite=None; Secure pour permettre leur inclusion dans un contexte tiers.

Cette fonctionnalité est le comportement par défaut à partir de la version stable de Chrome 84. Si vous ne l'avez pas déjà fait, mettez à jour les attributs de vos cookies tiers afin qu'ils ne soient pas bloqués à l'avenir.

Compatibilité multinavigateur

Consultez la section Compatibilité du navigateur de la page Set-Cookie de MDN.

Cas d'utilisation des cookies intersites ou tiers

Il existe un certain nombre de cas d'utilisation et de modèles courants dans lesquels les cookies doivent être envoyés dans un contexte tiers. Si vous fournissez l'un de ces cas d'utilisation ou dépendez-vous de l'un de ces cas d'utilisation, assurez-vous que le fournisseur ou vous-même mettez à jour ses cookies pour vous assurer que le service continue de fonctionner correctement.

Contenu d'un <iframe>

Le contenu d'un autre site affiché dans une <iframe> se trouve dans un contexte tiers. Voici quelques cas d'utilisation standards:

  • Contenu intégré partagé à partir d'autres sites, tel que des vidéos, des cartes, des exemples de code et des posts sur les réseaux sociaux.
  • Widgets de services externes tels que les paiements, les agendas, et les fonctionnalités de réservation et de réservation
  • Widgets tels que les boutons de réseaux sociaux ou les services antifraude qui créent des <iframes> moins évidents.

Les cookies peuvent être utilisés ici, entre autres, pour maintenir l'état de la session, stocker les préférences générales, activer des statistiques ou personnaliser le contenu des utilisateurs disposant d'un compte.

Schéma d&#39;une fenêtre de navigateur où l&#39;URL du contenu intégré ne correspond pas à celle de la page
Si le contenu intégré ne provient pas du même site que le contexte de navigation de premier niveau, il s'agit d'un contenu tiers.

En outre, le Web étant intrinsèquement composable, les <iframes> permettent d'intégrer du contenu qui s'affiche également dans un contexte de premier niveau ou propriétaire. Tous les cookies utilisés par ce site seront considérés comme des cookies tiers lorsque le site s'affiche dans le cadre. Si vous créez des sites que vous souhaitez intégrer facilement à d'autres sites tout en s'appuyant sur les cookies pour fonctionner, vous devez également vous assurer que ceux-ci sont marqués pour une utilisation intersite ou que vous pouvez utiliser les cookies de remplacement sans ces sites.

Demandes "non sécurisées" sur plusieurs sites

Bien que "non fiable" puisse sembler un peu inquiétant dans ce cas, il s'agit ici de toute requête susceptible de changer d'état. Sur le Web, il s'agit principalement de requêtes POST. Les cookies marqués comme SameSite=Lax seront envoyés lors de navigations de premier niveau sécurisées, par exemple lorsqu'un utilisateur cliquera sur un lien pour accéder à un autre site. En revanche, un envoi <form> via POST à un autre site n'inclura pas les cookies.

Schéma d&#39;une requête passant d&#39;une page à une autre.
Si la requête entrante utilise une méthode "sécurisée", les cookies sont envoyés.

Ce modèle est utilisé pour les sites susceptibles de rediriger l'utilisateur vers un service distant pour effectuer une opération avant un renvoi, par exemple la redirection vers un fournisseur d'identité tiers. Avant que l'utilisateur ne quitte le site, un cookie est défini. Il contient un jeton à usage unique. Il est prévu que ce jeton puisse être vérifié sur la requête renvoyée afin de limiter les attaques de falsification de requête intersites (CSRF). Si cette requête renvoyée provient de la méthode POST, vous devrez marquer les cookies comme SameSite=None; Secure.

Ressources distantes

Toute ressource distante d'une page peut s'appuyer sur des cookies envoyés avec une requête, à partir de balises <img>, <script>, etc. Les pixels de suivi et la personnalisation de contenu sont des cas d'utilisation courants.

Cela s'applique également aux requêtes lancées à partir de votre JavaScript par fetch ou XMLHttpRequest. Si fetch() est appelé avec l'option credentials: 'include', cela indique que des cookies peuvent être attendus sur ces requêtes. Pour XMLHttpRequest, vous devez rechercher les instances de la propriété withCredentials définie sur true. Cela indique que des cookies peuvent être attendus pour ces requêtes. Ces cookies devront être correctement marqués pour être inclus dans les requêtes intersites.

Contenu d'une WebView

Dans une application spécifique à une plate-forme, une WebView est alimentée par un navigateur. Vous devrez donc tester si les mêmes restrictions ou problèmes s'appliquent. Dans Android, si la WebView est fournie par Chrome, les nouveaux paramètres par défaut ne seront pas immédiatement appliqués avec Chrome 84. Cependant, l'intention est de les appliquer à l'avenir. Vous devez donc toujours les tester et vous y préparer. De plus, Android autorise ses applications spécifiques à la plate-forme à définir des cookies directement via l'API CookieManager. Comme pour les cookies définis via des en-têtes ou JavaScript, envisagez d'inclure SameSite=None; Secure s'ils sont destinés à être utilisés sur plusieurs sites.

Comment implémenter SameSite aujourd'hui

Pour les cookies qui ne sont nécessaires que dans un contexte propriétaire, vous devez idéalement les marquer comme SameSite=Lax ou SameSite=Strict, selon vos besoins. Vous pouvez également choisir de ne rien faire et de simplement autoriser le navigateur à appliquer sa valeur par défaut, mais cela peut entraîner un comportement incohérent entre les navigateurs et des avertissements potentiels dans la console pour chaque cookie.

Set-Cookie: first_party_var=value; SameSite=Lax

Pour les cookies nécessaires dans un contexte tiers, vous devez vous assurer qu'ils sont marqués comme SameSite=None; Secure. Notez que les deux attributs doivent être combinés. Si vous vous contentez de spécifier None sans Secure, le cookie sera refusé. Il existe cependant des différences incompatibles entre les mises en œuvre des navigateurs. Vous devrez donc peut-être utiliser certaines des stratégies d'atténuation décrites dans la section Gérer les clients incompatibles ci-dessous.

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

Gérer des clients incompatibles

Ces modifications visant à inclure None et le comportement par défaut de mise à jour sont encore relativement nouveaux. Par conséquent, il existe des incohérences entre les navigateurs quant à la manière dont ces modifications sont gérées. Vous pouvez consulter la page des mises à jour sur chromium.org pour connaître les problèmes connus, mais il n'est pas possible de déterminer si ceux-ci sont exhaustifs. Bien que ce ne soit pas idéal, il existe des solutions de contournement pendant cette phase de transition. La règle générale consiste toutefois à considérer les clients incompatibles comme un cas particulier. Ne créez pas d'exception pour les navigateurs qui implémentent les nouvelles règles.

La première consiste à définir à la fois les nouveaux et les anciens cookies:

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

Les navigateurs qui implémentent le comportement le plus récent définiront le cookie avec la valeur SameSite, tandis que d'autres navigateurs peuvent l'ignorer ou le définir de manière incorrecte. Toutefois, ces mêmes navigateurs définiront le cookie 3pcookie-legacy. Lors du traitement des cookies inclus, le site doit d'abord vérifier la présence du nouveau cookie de style. S'il est introuvable, le site doit ensuite utiliser l'ancien cookie.

L'exemple ci-dessous montre comment procéder dans Node.js, en utilisant le framework Express et son intergiciel d'cookie-parser.

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

L'inconvénient est que cela implique de définir des cookies redondants pour couvrir tous les navigateurs, et d'apporter des modifications au moment de la définition et de la lecture du cookie. Toutefois, cette approche devrait couvrir tous les navigateurs, quel que soit leur comportement, et garantir que les cookies tiers continuent de fonctionner comme avant.

Vous pouvez également choisir de détecter le client via la chaîne user-agent au moment d'envoyer l'en-tête Set-Cookie. Reportez-vous à la liste des clients incompatibles, puis utilisez une bibliothèque adaptée à votre plate-forme, par exemple la bibliothèque ua-parser-js sur Node.js. Il est recommandé de trouver une bibliothèque pour gérer la détection des user-agents, car vous ne souhaitez probablement pas écrire ces expressions régulières vous-même.

L'avantage de cette approche est qu'elle ne nécessite d'apporter qu'une seule modification au moment de définir le cookie. Toutefois, l'avertissement nécessaire ici est que le reniflage par le user-agent est intrinsèquement fragile et risque de ne pas détecter tous les utilisateurs concernés.

Prise en charge de SameSite=None dans les langages, les bibliothèques et les frameworks

La plupart des langages et des bibliothèques acceptent l'attribut SameSite pour les cookies, mais l'ajout de SameSite=None est encore relativement récent. Vous devrez donc peut-être contourner certains comportements standards pour le moment. Celles-ci sont documentées dans le dépôt d'exemples SameSite sur GitHub.

Obtenir de l'aide

Les cookies sont omniprésents, et il est rare qu'un site ait entièrement audité l'endroit où ils sont définis et utilisés, en particulier si vous combinez des cas d'utilisation intersites. Lorsque vous rencontrez un problème, il peut s'agir de la première fois que quelqu'un le rencontre. N'hésitez donc pas à nous contacter: