Seguridad digital

JWT en Cookies: seguridad de sesiones en aplicaciones escalables

En el desarrollo de aplicaciones web modernas, la gestión segura de la sesión del usuario no es un detalle menor, sino un pilar fundamental de la arquitectura de seguridad. El uso de JSON Web Tokens (JWT) se ha estandarizado como el mecanismo ideal para implementar autenticación sin estado. Sin embargo, a nivel técnico, surge una pregunta crítica que afecta directamente la postura de seguridad de cualquier plataforma en crecimiento: ¿dónde almacenás ese JWT en el cliente de forma segura?

Las dos alternativas más comunes que se debaten son LocalStorage y Cookies. En este análisis, vamos a profundizar en las vulnerabilidades de cada opción frente a amenazas comunes (XSS y CSRF) y justificaremos por qué la implementación de cookies con atributos de seguridad específicos es la estrategia de seguridad por defecto para sistemas robustos.

Mecanismos de almacenamiento: Conveniencia vs. Robustez

Para tomar una decisión informada, es crucial entender cómo funciona cada mecanismo y los atributos que marcan la diferencia en términos de seguridad.

LocalStorage

LocalStorage es una API simple que permite almacenar pares clave-valor en el navegador.

  • Acceso abierto a JavaScript: Su principal característica, y su mayor riesgo, es que cualquier script JavaScript que se ejecute en la página tiene acceso completo a sus datos.

  • Vulnerabilidad a XSS: Si un atacante logra inyectar código malicioso (Cross-Site Scripting – XSS), puede leer el JWT directamente con localStorage.getItem(‘jwt_token’) y enviarlo a su propio servidor.

  • Consecuencia del robo: El atacante obtiene una copia del token, lo que resulta en un robo total y persistente de la sesión. Puede suplantar al usuario libremente hasta que el token expire.
  • Seguridad frágil: LocalStorage no ofrece ningún mecanismo de protección inherente contra esto. Su seguridad depende al 100% de que tu aplicación sea impenetrable a cualquier XSS, algo que es difícil de garantizar.

Cookies

Las cookies son pequeños ficheros de datos que se reenvían automáticamente al servidor en futuras peticiones. A diferencia de LocalStorage, las cookies se pueden fortificar drásticamente con atributos específicos para la seguridad.

 

Atributo Objetivo principal Defensa clave
HttpOnly Impide que el valor de la cookie sea accesible desde la API de JavaScript (Document.cookie). Mitiga el robo de sesiones a través de ataques XSS
Secure Asegura que la cookie solo se envíe a través de una conexión cifrada (HTTPS). Protege la información de la cookie contra ataques de Man-in-the-Middle (MitM).
SameSite Es la defensa más moderna y eficaz contra CSRF. Controla si la cookie se envía en solicitudes que se originan en sitios diferentes. Bloquea la mayoría de las peticiones de origen cruzado, neutralizando los ataques CSRF.

La fortaleza de HttpOnly contra XSS

Una cookie marcada como HttpOnly es inaccesible para JavaScript. Incluso si un atacante logra inyectar un script, no puede robar el token. El navegador la gestiona y la envía, neutralizando el principal vector de ataque del XSS: el robo de la credencial para uso externo.

La solución moderna para CSRF: SameSite

Históricamente, el gran argumento en contra de las cookies era su vulnerabilidad intrínseca a CSRF, ya que se envían automáticamente con cada petición. Sin embargo, el atributo SameSite ha resuelto este problema en gran medida.

Al configurarlo como Lax (un buen equilibrio entre seguridad y usabilidad) o Strict, se le indica al navegador que bloquee el envío de la cookie en la mayoría de las solicitudes que se originan desde otros dominios

Análisis comparativo de amenazas

La elección no se trata de cuál es más “moderno”, sino de cuál ofrece un mejor modelo de seguridad frente a las amenazas más comunes y peligrosas.

Características LocalStorage Cookie HttpOnly Cookie HttpOnly + SameSite
Protección XSS ❌ Vulnerable (Robo total) ✅ Protegido (Robo mitigado) ✅ Protegido (Robo mitigado)
Protección CSRF ✅ Protegido ❌ Vulnerable ✅ Protegido
Recomendación No recomendado Parcialmente seguro Recomendado


La estrategia que proporciona protección completa contra ambos vectores de ataque principales es el uso de Cookies con
HttpOnly y SameSite. Estás construyendo una defensa por capas, aprovechando el navegador para hacer cumplir la seguridad por vos.

Otros temas

Desafíos de implementación con HttpOnly

Adoptar cookies HttpOnly significa que tu frontend no puede inspeccionar el JWT. Esto requiere un cambio en la gestión de la sesión y el logout.

La solución es inferir el estado de la sesión.

  • Al cargarse, la aplicación intenta realizar una petición a un endpoint protegido (ej. GET /api/user/profile).
  • Si el servidor responde con un código 200 (éxito), la sesión está activa y el frontend actualiza la interfaz.
  • Si el servidor responde con un código 401 (Unauthorized), no hay una cookie válida, por lo que no hay sesión, y el frontend redirige al login.

 

Dado que el frontend no puede tocar una cookie HttpOnly, el logout debe ser una operación del servidor.

  • El frontend realiza una petición a un endpoint específico del backend (ej. POST /api/logout).
  • El servidor recibe la petición y responde enviando un encabezado Set-Cookie que instruye al navegador a eliminar la cookie (estableciendo una fecha de expiración en el pasado, o una duración de cero).
  • El frontend solo limpia su estado local y redirige al login.

 

Implementación en proyectos existentes

Si estás pensando en migrar un proyecto existente para adoptar esta estrategia, es totalmente posible y se puede hacer de forma gradual.

La clave es extender tu lógica de autenticación (filters) para priorizar la lectura del token desde la cookie de access token, si existe, manteniendo la compatibilidad con el header (como el Authorization: Bearer Token tradicional) para otros clientes.

Además, es fundamental establecer endpoints específicos en el backend para manejar el ciclo de vida del token, como el refresh y el logout.

Finalmente, no olvides que al usar cookies, debés habilitar las credenciales en la configuración CORS de tu backend para permitir que el frontend envíe las cookies en las peticiones de origen cruzado.

El camino hacia la seguridad pasa por entender los riesgos y aprovechar las herramientas que nos brindan los estándares modernos. Implementar JWT mediante cookies con HttpOnly y SameSite es, sin duda, la decisión más sólida que podés tomar hoy para proteger a tus usuarios.

Conclusión

La seguridad en aplicaciones escalables no permite atajos. Si bien LocalStorage ofrece una implementación rápida, solo el uso de Cookies con atributos HttpOnly y SameSite proporciona la robusta línea de defensa que exigen los estándares actuales contra ataques XSS y CSRF. Implementar JWT de esta manera no es solo una buena práctica; es la decisión más sólida para proteger la integridad de tus usuarios y la reputación de tu plataforma.

¿Necesitás auditar la seguridad de tus sesiones?

En Meta ayudamos a empresas a construir arquitecturas web blindadas.

También te puede interesar

  • 24 enero, 2024

    Automatización de procesos

  • 30 mayo, 2024

    Beneficios de la integración y despliegue continuo

    Tags: ,
  • 19 julio, 2024

    La Nube: revolucionando el mundo de los negocios