Recetas de galletas de SameSite

Chrome, Firefox, Edge y otros están cambiando su comportamiento predeterminado de acuerdo con la propuesta de IETF llamada Mejores cookies de forma incremental para lograr lo siguiente:

  • Las cookies sin un atributo SameSite se tratan como SameSite=Lax, lo que significa que el comportamiento predeterminado es restringir las cookies a contextos propios solo.
  • Las cookies para el uso entre sitios deben especificar SameSite=None; Secure para permitir la inclusión en un contexto de terceros.

Si aún no lo hiciste, debes actualizar los atributos de las cookies de terceros para que no se bloqueen en el futuro.

Navegadores compatibles

  • 51
  • 16
  • 60
  • 13

Origen

Casos de uso de cookies entre sitios o de terceros

Hay una serie de casos de uso y patrones comunes en los que se deben enviar cookies en un contexto de terceros. Si proporcionas uno de estos casos de uso o dependes de ellos, asegúrate de que tú o el proveedor actualicen las cookies para que el servicio siga funcionando correctamente.

Contenido dentro de una <iframe>

El contenido de un sitio diferente que se muestra en una <iframe> está en un contexto de terceros. Entre los casos de uso estándar, se incluyen los siguientes:

  • Contenido incorporado que se comparte desde otros sitios, como videos, mapas, muestras de código y publicaciones en redes sociales
  • Widgets de servicios externos, como funciones de pagos, calendarios y reservas
  • Widgets, como botones de redes sociales o servicios contra fraudes que crean <iframes> menos evidentes

Aquí se pueden usar cookies para, entre otras cosas, mantener el estado de la sesión, almacenar preferencias generales, habilitar estadísticas o personalizar el contenido para los usuarios con cuentas existentes.

Diagrama de una ventana del navegador donde la URL del contenido incorporado no coincide con la de la página.
Si el contenido incorporado no proviene del mismo sitio que el contexto de navegación de nivel superior, es contenido de terceros.

Como la Web es componible de forma inherente, también se usan <iframes> para incorporar contenido que se visualiza en un contexto propio o de nivel superior. Todas las cookies que el sitio muestra en el iframe usa se consideran cookies de terceros. Si creas sitios que quieres que incorporen otros sitios y necesitas cookies para que funcionen, también debes asegurarte de que estén marcados para el uso entre sitios o de que puedas recurrir a ellos sin ellos.

Solicitudes "no seguras" en diferentes sitios

En este caso, el término "no seguro" puede sonar preocupante, pero se refiere a cualquier solicitud que podría cambiar de estado. En la Web, esto son principalmente solicitudes POST. Las cookies marcadas como SameSite=Lax se envían en navegaciones seguras de nivel superior, como hacer clic en un vínculo para ir a un sitio diferente. Sin embargo, algo como un envío de <form> a un sitio diferente mediante POST no incluye cookies.

Diagrama de una solicitud que pasa de una página a otra
Si la solicitud entrante usa un método "seguro", la página envía cookies.

Este patrón se usa para los sitios que pueden redireccionar al usuario a un servicio remoto para realizar alguna operación antes de regresar, por ejemplo, redireccionarlos a un proveedor de identidad de terceros. Antes de que el usuario abandone el sitio, se configura una cookie que contiene un solo token de uso con la expectativa de que este token se pueda verificar en la solicitud que se muestra para mitigar los ataques de falsificación de solicitudes entre sitios (CSRF). Si esa solicitud que se muestra proviene de POST, deberás marcar las cookies como SameSite=None; Secure.

Recursos remotos

Cualquier recurso remoto en una página, como desde las etiquetas <img> o <script>, puede depender del envío de cookies con una solicitud. Algunos casos de uso comunes son el seguimiento de píxeles y la personalización del contenido.

Esto también se aplica a las solicitudes enviadas desde tu JavaScript con fetch o XMLHttpRequest. Si se llama a fetch() con la opción credentials: 'include', es probable que esas solicitudes incluyan cookies. Para XMLHttpRequest, las cookies esperadas suelen indicarse con un valor withCredentials en true. Esas cookies deben estar marcadas de forma correcta para que se incluyan en solicitudes entre sitios.

Contenido dentro de WebView

Una WebView en una app específica de la plataforma funciona con la tecnología de un navegador. Los desarrolladores deben probar si las restricciones o los problemas que afectan a sus apps también se aplican a sus WebViews.

Android también permite que las apps específicas de su plataforma configuren cookies directamente con la API de CookieManager. Al igual que con las cookies configuradas mediante encabezados o JavaScript, considera incluir SameSite=None; Secure si están diseñadas para el uso entre sitios.

Cómo implementar SameSite hoy mismo

Marca las cookies que solo sean necesarias en un contexto propio como SameSite=Lax o SameSite=Strict según tus necesidades. Si no marcas estas cookies y dependes del comportamiento predeterminado del navegador para controlarlas, estas pueden comportarse de manera inconsistente en todos los navegadores y, posiblemente, activar advertencias de la consola para cada cookie.

Set-Cookie: first_party_var=value; SameSite=Lax

Asegúrate de marcar las cookies necesarias en un contexto de terceros como SameSite=None; Secure. Ambos atributos son obligatorios. Si solo especificas None sin Secure, se rechazará la cookie. Para tener en cuenta las diferencias en las implementaciones de navegadores, es posible que debas usar algunas de las estrategias de mitigación descritas en Cómo controlar clientes incompatibles.

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

Cómo controlar clientes incompatibles

Debido a que estos cambios para incluir None y actualizar el comportamiento predeterminado son relativamente nuevos, los diferentes navegadores los manejan de manera diferente. Puedes consultar la página de actualizaciones en chromium.org para obtener una lista de los problemas conocidos, pero es posible que la lista no sea exhaustiva.

Una solución posible es configurar cada cookie en el estilo nuevo y en el anterior:

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

Los navegadores que implementan el comportamiento más reciente establecen la cookie con el valor SameSite. Los navegadores que no implementan el nuevo comportamiento ignoran ese valor y establecen la cookie 3pcookie-legacy. Cuando procesa las cookies incluidas, tu sitio primero debe verificar la presencia del estilo nuevo de cookie y, luego, recurrir a la cookie heredada si no puede encontrar una nueva.

En el siguiente ejemplo, se muestra cómo hacerlo en Node.js, con el framework Express y su middleware 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);

Este enfoque requiere que realices un trabajo adicional para configurar cookies redundantes y realizar cambios en el momento de configurar y leer la cookie. Sin embargo, debe cubrir todos los navegadores, independientemente de su comportamiento, y mantener las cookies de terceros funcionando.

Como alternativa, puedes detectar el cliente con la string de usuario-agente cuando se envía un encabezado Set-Cookie. Consulta la lista de clientes incompatibles y usa una biblioteca de detección de usuario-agente adecuada para tu plataforma, por ejemplo, la biblioteca ua-parser-js en Node.js. Este enfoque solo requiere que realices un cambio, pero es posible que el detector de usuarios-agentes no detecte a todos los usuarios afectados.

Compatibilidad con SameSite=None en lenguajes, bibliotecas y frameworks

La mayoría de los lenguajes y las bibliotecas admiten el atributo SameSite para las cookies. Sin embargo, dado que la adición de SameSite=None sigue siendo relativamente reciente, es posible que debas solucionar algún comportamiento estándar por el momento. Estos comportamientos están documentados en el repositorio de ejemplos de SameSite en GitHub.

Cómo obtener ayuda

Las cookies se usan en todas partes de la Web, y es poco frecuente que cualquier equipo de desarrollo tenga un conocimiento completo de dónde las configura y usa su sitio, especialmente en los casos de uso de varios sitios. Cuando tienes un problema, es posible que sea la primera vez que alguien lo encuentra, así que no dudes en comunicarte con nosotros: