Resumen

Guardar un token JWT parece una decisión sencilla, pero tiene implicaciones directas en la seguridad de toda tu aplicación. La mayoría de tutoriales en Internet recomiendan local storage, y sin embargo, ningún almacenamiento en la web es completamente seguro. La clave está en reconocer las vulnerabilidades de cada opción y tomar medidas adicionales para mitigarlas.

¿Qué vulnerabilidades afectan el almacenamiento de tokens JWT?

Existen dos tipos de ataques principales que determinan qué tan seguro es el lugar donde guardas tu token: Cross-Site Request Forgery (CSRF) y Cross-Site Scripting (XSS) [0:28]. Dependiendo de la opción de almacenamiento que elijas, estarás expuesto a uno u otro.

¿Por qué las cookies seguras son vulnerables a CSRF?

Cuando utilizas cookies configuradas como HTTP only y con el atributo sameSite, obtienes una buena protección base contra XSS. Sin embargo, como las cookies siempre se envían automáticamente al servidor con cada request, quedas expuesto a ataques de CSRF [0:55]. Un atacante podría generar una solicitud maliciosa que el servidor interpretaría como legítima, porque la cookie viaja junto con ella. El servidor necesita una protección adicional para distinguir si esa solicitud realmente proviene del usuario.

¿Qué riesgos tienen session storage y local storage?

Tanto session storage como local storage están protegidos contra CSRF, ya que sus valores nunca se envían automáticamente al servidor [1:18]. Todo envío debe hacerse manualmente con JavaScript. El problema es que quedan expuestos a ataques de XSS. Si un código malicioso se inyecta en tu aplicación, puede leer los valores almacenados.

Este riesgo no es tan lejano como parece. Piensa en NPM: cada vez dependemos más de librerías y dependencias externas [1:46]. Podría suceder que una de ellas, de procedencia dudosa, inyecte código malicioso. El navegador no distingue si ese JavaScript pertenece a tu aplicación o a una librería comprometida.

¿Qué recomienda OWASP para guardar tokens JWT?

La organización OWASP sugiere como primera opción guardar el token en session storage [2:18], que es volátil y está protegido contra CSRF. Para mitigar el riesgo de XSS, recomienda agregar un fingerprint: una cadena única que solo el servidor puede crear, almacenada en una cookie [2:36]. Al momento de validar, el servidor espera recibir tanto el token del session storage como el fingerprint de la cookie. Ambos valores deben ser válidos para autorizar cualquier operación.

Si prefieres usar cookies, OWASP indica que es prácticamente obligatorio que sean seguras:

  • Tener un sitio HTTPS es el paso cero para garantizar seguridad [3:02].
  • Agregar el atributo HTTP only para que el front-end no pueda manipular la cookie [3:14].
  • Incluir una protección adicional contra CSRF mediante otra cookie que se envía junto con el token para validar que el request sea legítimo [3:38].

¿Cómo gestiona NextAuth la seguridad del token JWT?

NextAuth implementa una de las configuraciones más seguras por defecto [4:18]. El JWT se crea en el servidor que corre Next.js sobre Node.js. La cookie resultante se configura como HTTP only, lo que impide que el front-end acceda directamente al token [4:30]. Para que el cliente obtenga información de la sesión, debe hacer un request adicional al servidor.

Esta arquitectura es especialmente robusta porque:

  • El front-end nunca tiene acceso directo al token ni conoce el secreto para desencriptarlo [4:48].
  • Todas las operaciones sensibles pasan a través del servidor.
  • NextAuth ofrece protección CSRF integrada en las páginas de inicio de sesión y logout [5:06].
  • Con la utilidad getCSRF puedes extender esta protección a cualquier otra página [5:22].

¿Qué pasa cuando no hay servidor de por medio?

Toda esta estrategia funciona bien cuando tienes control sobre un servidor [5:36]. Cuando tu aplicación corre únicamente en el cliente, sin un servidor que la respalde, la historia cambia por completo y se necesitan estrategias avanzadas diferentes para proteger los tokens.

La decisión de dónde almacenar un JWT no debería tomarse a la ligera. Comparte en los comentarios qué estrategia has utilizado en tus proyectos y si has enfrentado alguna de estas vulnerabilidades.