Skip to content

La realidad del almacenamiento de tokens en el navegador

Una mirada práctica a JWT en navegador: XSS, CSRF, cookies, localStorage, service workers y decisiones de amenaza.

Publicado el 3 min de lectura

Los debates sobre almacenamiento de tokens en navegador suelen reducirse a lemas: localStorage es malo, cookies son buenas, o al revés. Las aplicaciones reales necesitan un modelo de amenaza. Un JWT en localStorage es fácil de leer para JavaScript inyectado. Un JWT en una cookie HttpOnly no puede leerse directamente desde script, pero se envía automáticamente con requests y necesita controles CSRF. Ninguna opción salva a una app con XSS amplio y APIs privilegiadas sin verificación adicional.

Qué quiere el atacante

Con XSS, el atacante pregunta primero si puede robar el token o si basta con usar el navegador de la víctima como delegado confundido. Si el token está en localStorage, localStorage.getItem("access_token") es el camino obvio. Si está en una cookie HttpOnly, el robo directo es más difícil, pero el atacante todavía puede llamar APIs same-origin desde la página salvo que CSP, validación de requests y confirmaciones para acciones sensibles reduzcan el impacto.

La vida del token cambia el cálculo. Un access token de cinco minutos en memoria con una cookie de refresh se comporta muy distinto a un JWT de treinta días en localStorage. Extensiones de navegador, equipos compartidos, volcados de crash, logs y capturas para soporte también importan. La decisión de almacenamiento no vive separada de operaciones.

Patrones comunes y costes

Guardar access tokens solo en memoria reduce el robo persistente, pero complica recargas, múltiples pestañas y flujos offline. Cookies HttpOnly Secure SameSite funcionan bien para muchas apps web, aunque dominios API cruzados y contextos embebidos pueden volver delicada la configuración de SameSite. localStorage es simple y predecible, pero cada XSS se convierte en extracción de token si el token no es corto y de alcance limitado.

Detalles defensivos que cuentan

Configura Secure, HttpOnly y un valor SameSite deliberado en cookies. Usa CSP con nonces o hashes, no una política que permita ejecutar script a cualquier dominio de analítica. Evita tokens en URLs, porque se filtran por historial, referrers, logs de proxy y capturas. No imprimas bearer tokens en telemetría frontend. Limpia encabezados Authorization antes de que lleguen a herramientas de session replay.

Probar la decisión

En una revisión, simula al atacante y no el diagrama. ¿Un script inyectado puede leer el token? ¿Puede llamar a /api/export o /api/billing con cookies ambientales? ¿El logout revoca el camino de refresh o solo borra estado cliente? Abre DevTools, inspecciona storage, dispara errores y revisa payloads de telemetría. El mejor diseño es aquel cuyo modo de fallo ya probaste.

Artículos relacionados

Cómo inspeccionar problemas JWT de forma segura en logs, tickets, CLI, capturas y canales de incidente sin propagar bearer tokens.
Guía operativa para claves de firma JWT: generación, almacenamiento, KMS, rotación, control de acceso, auditoría y respuesta.
Una secuencia probada para evaluar JWT: captura, decodificación, claims, claves, replay y reporte.