- Cookies HTTP: pequeños fragmentos de datos usados para mantener el estado en la web, que el navegador incluye en todas las solicitudes HTTP desde que se configuran hasta que expiran.
- Aparición del problema: cierto código JavaScript provocó un error porque la biblioteca estándar de Go no pudo parsear las cookies.
Especificación
- RFC 2109, 2965, 6265: definiciones iniciales y actualizaciones de las cookies. La especificación sobre los valores de las cookies no coincide entre el servidor y el navegador.
- Problemas:
- Lo que el servidor debe enviar y lo que el navegador debe aceptar no coincide.
- No hay restricciones sobre los valores de cookies que el navegador envía al servidor.
- No hay una guía clara sobre cómo deben procesar los encabezados de cookies las bibliotecas estándar.
Navegadores web
- Firefox: permite algunos caracteres que la RFC no recomienda.
- Chromium: es un poco más restrictivo que Firefox, pero aun así permite muchos caracteres.
- Safari: cuando encuentra un carácter no permitido, no detiene el procesamiento de la cookie y acepta el valor hasta ese carácter.
Bibliotecas estándar
- Golang: se comporta de forma similar a la RFC, pero permite espacios y comas.
- PHP: genera errores con ciertos caracteres de control.
- Python: ignora las cookies que no entiende y deja de cargar cookies adicionales.
- Ruby: acepta todos los caracteres y les aplica codificación porcentual.
- Rust: acepta cualquier cadena UTF-8.
Importancia para la web
- Problema real: debido a la ambigüedad de la especificación, muchos sitios web pueden fallar con facilidad.
- Solución: el IETF HTTP Working Group debe actualizar la especificación de cookies y aclarar cómo los navegadores y los lenguajes de programación deben procesarlas.
Tabla resumen
- Procesamiento de cookies en navegadores y lenguajes: la forma en que cada navegador y lenguaje procesa las cookies es distinta. También varía su nivel de cumplimiento con la RFC.
1 comentarios
Comentarios de Hacker News
Las cookies incluyen problemas inesperados y comportamientos incómodos, aunque funcionan en el 99.95% de los casos. El sombreado de cookies ocurre al configurar cookies con el mismo nombre pero con distintos atributos clave, como dominio o ruta, y ni el backend ni JS pueden distinguir cuál cookie es cuál
Rust no tiene funcionalidad de manejo de cookies en la biblioteca estándar y toma como referencia el comportamiento del crate de terceros "cookie". Este incluye una opción de percent-encoding, como Ruby
El protocolo HTTP contiene dentro de sí muchísimos otros protocolos, y los navegadores y servidores web añaden varias funcionalidades. Estas funciones no tienen una especificación clara, y ni el cliente ni el servidor pueden indicar compatibilidad. Por eso hay que seguir arrastrando malas decisiones del pasado
Hace unos 10 años, al implementar sesiones basadas en cookies en un proyecto, hubo un problema que funcionaba en Safari pero no en Chrome. Esto se debía a la diferencia en que los navegadores no establecen la cookie si el formato no es correcto
El único uso razonable de las cookies es establecer un token opaco para que el servidor pueda reconocer al cliente. No es un problema que el cliente pueda manejar valores que el servidor no enviaría
Las cookies son un problema complejo y es casi imposible cambiarlas por cuestiones de compatibilidad hacia atrás. Hace falta crear un mecanismo nuevo. Por ejemplo, un mecanismo NewCookie podría tener medidas de seguridad modernas y una especificación estricta
Las cookies deberían desaparecer y podrían reemplazarse por encabezados de autenticación. Sería bueno que existiera una forma estándar de autenticarse con un sitio web desde el navegador. Es una lástima que la autenticación Basic y Digest no hayan sido suficientes
Como el código de red de Safari no es de código abierto, el port de Foundation de Swift podría ser una buena alternativa. Ahí se pueden revisar los caracteres de control y de borrado
El parseo del encabezado Cookie es confuso. El "estándar" no refleja lo que realmente existe, y cada servidor backend, biblioteca o framework acepta cosas distintas. Si puedes controlar por completo el frontend y el backend, no es un gran problema, pero cuando tienes que interactuar con otros sistemas se vuelve muy complejo
Al experimentar con el lenguaje Crystal, se encontró un problema similar. Se intentó construir un web scraper simple, pero el cliente HTTP básico no podía parsear muchas de las cookies establecidas en la respuesta y se detenía