Recetas de galletas de SameSite

Chrome, Firefox, Edge y otros navegadores están cambiando su comportamiento predeterminado de acuerdo con la propuesta del IETF, Incrementally Better Cookies, de modo que:

  • Las cookies sin un atributo SameSite se consideran SameSite=Lax, lo que significa que el comportamiento predeterminado es restringir las cookies a los contextos de origen únicamente.
  • Las cookies para el uso en varios sitios deben especificar SameSite=None; Secure para habilitar la inclusión en el contexto de terceros.

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

Browser Support

  • Chrome: 51.
  • Edge: 16.
  • Firefox: 60.
  • Safari: 13.

Source

Casos de uso de cookies de terceros o de sitios cruzados

Existen varios casos de uso y patrones comunes en los que las cookies deben enviarse en un contexto de terceros. Si proporcionas o dependes de uno de estos casos de uso, asegúrate de que tú o el proveedor actualicen sus cookies para que el servicio siga funcionando correctamente.

Contenido dentro de un <iframe>

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

  • Contenido incorporado compartido desde otros sitios, como videos, mapas, muestras de código y publicaciones en redes sociales
  • Widgets de servicios externos, como funciones de pagos, calendarios, reservas y reservaciones
  • Widgets, como botones de redes sociales o servicios antifraude, que crean <iframes> menos obvios.

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 en el que la URL del contenido incorporado no coincide con la URL de la página.
Si el contenido incorporado no proviene del mismo sitio que el contexto de navegación de nivel superior, se trata de contenido de terceros.

Dado que la Web es inherentemente componible, los <iframes> también se usan para incorporar contenido que se ve en un contexto de nivel superior o de origen. Las cookies que usa el sitio que se muestra en el iframe se consideran cookies de terceros. Si creas sitios que quieres que otros sitios incorporen y necesitas cookies para que funcionen, también debes asegurarte de que estén marcadas para el uso entre sitios o de que puedas recurrir a una alternativa sin problemas si no las tienes.

Solicitudes "inseguras" en sitios

Es posible que "inseguro" suene preocupante, pero se refiere a cualquier solicitud que pueda tener la intención de cambiar el estado. En la Web, se trata principalmente de solicitudes POST. Las cookies marcadas como SameSite=Lax se envían en navegaciones seguras de nivel superior, como cuando se hace clic en un vínculo para ir a otro sitio. Sin embargo, una solicitud <form> a un sitio diferente con POST no incluye cookies.

Diagrama de una solicitud que se mueve 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, redireccionar a un proveedor de identidad externo. Antes de que el usuario abandone el sitio, se establece una cookie que contiene un token de un solo uso con la expectativa de que este token se pueda verificar en la solicitud de devolución para mitigar los ataques de falsificación de solicitudes entre sitios (CSRF). Si esa solicitud de devolución se realiza a través de POST, deberás marcar las cookies como SameSite=None; Secure.

Recursos remotos

Cualquier recurso remoto en una página, como los provenientes de etiquetas <img> o <script>, podría depender de que se envíen cookies con una solicitud. Los casos de uso comunes incluyen los píxeles de seguimiento y la personalización del contenido.

Esto también se aplica a las solicitudes que envías desde JavaScript con fetch o XMLHttpRequest. Si se llama a fetch() con la opción credentials: 'include', es probable que esas solicitudes incluyan cookies. En el caso de XMLHttpRequest, las cookies esperadas suelen indicarse con un valor de withCredentials para true. Esas cookies deben estar marcadas de forma adecuada para que se incluyan en las solicitudes de sitios cruzados.

Contenido dentro de un WebView

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

Android también permite que sus apps específicas de la plataforma establezcan cookies directamente con la API de CookieManager. Al igual que con las cookies establecidas con encabezados o JavaScript, considera incluir SameSite=None; Secure si están destinadas a usarse en varios sitios.

Cómo implementar SameSite hoy mismo

Marca las cookies que solo se necesiten en un contexto de origen como SameSite=Lax o SameSite=Strict, según tus necesidades. Si no marcas estas cookies y, en cambio, confías en el comportamiento predeterminado del navegador para controlarlas, pueden comportarse de manera incoherente en los distintos navegadores y, potencialmente, activar advertencias de la consola para cada cookie.

Set-Cookie: first_party_var=value; SameSite=Lax

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

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

Cómo controlar clientes incompatibles

Dado que estos cambios para incluir None y actualizar el comportamiento predeterminado son relativamente nuevos, los diferentes navegadores los controlan de distintas maneras. Puedes consultar la página de actualizaciones en chromium.org para ver una lista de los problemas conocidos, pero es posible que esta lista no sea exhaustiva.

Una posible solución alternativa es establecer 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 procese las cookies incluidas, su sitio primero debe verificar la presencia del nuevo estilo de cookie y, luego, recurrir a la cookie heredada si no encuentra una nueva.

En el siguiente ejemplo, se muestra cómo hacerlo en Node.js con el framework de 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 trabajo adicional para configurar cookies redundantes y realizar cambios en el momento de configurar y leer la cookie. Sin embargo, debe abarcar todos los navegadores, independientemente de su comportamiento, y mantener el funcionamiento de las cookies de terceros.

Como alternativa, puedes detectar el cliente con la cadena 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 agentes de usuario adecuada para tu plataforma, por ejemplo, la biblioteca ua-parser-js en Node.js. Este enfoque solo requiere que realices un cambio, pero la detección del agente de usuario podría no identificar 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, debido a que la incorporación de SameSite=None es relativamente reciente, es posible que debas solucionar algunos comportamientos estándares por el momento. Estos comportamientos se documentan en el repositorio de ejemplos de SameSite en GitHub.

Cómo obtener ayuda

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