flawopen.com/Referencia/JWT frente a cookies HttpOnly
JWT en localStorage frente a cookies HttpOnly: ¿qué es más seguro?
Para muchas aplicaciones web, una sesión administrada por el servidor y entregada en una cookie HttpOnly es un buen punto de partida. JavaScript no puede leer esa cookie, lo que reduce la extracción del token, pero no neutraliza XSS: el código inyectado del mismo origen aún puede hacer solicitudes autenticadas y leer datos disponibles para la página.
Las contrapartidas de seguridad
| Almacenamiento / envío | Exposición a XSS | Comportamiento CSRF | Revocación |
|---|---|---|---|
localStorage bearer token | JavaScript del mismo origen puede leerlo; XSS puede robarlo o actuar como usuario. | No se adjunta automáticamente a solicitudes entre sitios; XSS y CSRF del lado del cliente siguen siendo riesgos. | Un JWT autocontenido puede seguir válido hasta expirar si no se comprueba su revocación. |
HttpOnly cookie | JavaScript no puede leer el valor; XSS aún puede enviar solicitudes autenticadas. | Se envía automáticamente según las reglas de cookies; SameSite es solo una capa CSRF. | La sesión opaca puede invalidarse en el servidor; un JWT en cookie requiere su propia política. |
Arquitectura recomendada
- ✓Guarda los identificadores de sesión en cookies
HttpOnly; Secure; SameSite=Lax. - ✓Evita guardar tokens de autenticación persistentes en
localStorageosessionStorage.
Separa el formato del token, el almacenamiento y el estado de sesión
JWT es un formato de token; localStorage y las cookies son mecanismos de almacenamiento y envío del navegador. Un JWT puede guardarse en cualquiera. Un identificador de sesión opaco en una cookie suele apuntar al estado administrado por el servidor. “JWT o cookie” no es una comparación directa entre alternativas equivalentes.
Qué cambia con cada opción
El navegador no adjunta automáticamente valores de localStorage a solicitudes entre sitios, pero XSS del mismo origen puede leer un bearer token guardado o actuar mediante la aplicación. Las cookies se envían automáticamente según las reglas del navegador; HttpOnly oculta el valor a JavaScript, pero no impide que código inyectado use la página autenticada. SameSite=Lax es una capa CSRF, no una garantía completa: las navegaciones de nivel superior con métodos seguros y las solicitudes same-site siguen importando. No cambies el estado mediante GET y aplica una defensa CSRF adecuada, como tokens validados y/o comprobaciones de Origin.
La revocación depende del estado del servidor y de la validación del token, no del lugar de almacenamiento. Una sesión del servidor puede invalidarse al eliminar su registro. Un JWT autocontenido puede seguir aceptándose hasta expirar salvo que se compruebe la revocación; una vigencia corta reduce esa ventana, pero no la elimina.
Punto de partida práctico
- ✓En una aplicación web propia, prefiere una sesión opaca del lado del servidor o un Backend-for-Frontend (BFF) cuando encaje.
- ✓Configura las cookies de sesión con
Secure,HttpOnly, unSameSitedeliberado,Path=/y, si es posible, sinDomain; considera__Host-. - ✓Usa tokens CSRF y/o validación de Origin en solicitudes que cambian estado según el modelo de amenazas; nunca cambies estado mediante
GET. - ✓Si necesitas JWT en el navegador, usa una vigencia corta, define cierre de sesión/revocación y prevén XSS. La cookie no sustituye los controles de autorización.