Glosario
¿Qué es un JWT (JSON Web Token)? Cómo funciona el pase firmado y cómo usarlo de forma segura
Un JWT (JSON Web Token) es un 'pase' a prueba de manipulación que un servidor firma. Cómo funcionan el encabezado/carga útil/firma y los peligros: omitir la verificación de la firma, permitir alg:none y poner secretos en la carga útil.
"El pase firmado que un servidor te entrega tras iniciar sesión": eso es un JWT. Aquí tienes cómo funciona y los puntos clave para usarlo de forma segura (sin pasos de ataque).
Cómo funciona (tres partes)
Un JWT es encabezado.carga_útil.firma unido con .. El encabezado y la carga útil están solo codificados en base64url (no cifrados); únicamente la firma se hace con una clave secreta (o compartida).
1. encabezado
metadatos como el algoritmo de firma. cualquiera puede leerlo
2. carga útil
claims como el id de usuario y la expiración. cualquiera puede leer = sin secretos
3. firma
hecha con una clave. garantiza que no hay manipulación
El punto clave es que el contenido es "solo legible". Así que la carga útil no es lugar para contraseñas ni datos personales. El valor de un JWT es que, al verificar la firma, el servidor puede confirmar "yo emití este token y no ha sido alterado".
Defensas para usarlo de forma segura
Verifica siempre la firma y fija el alg (lo más importante)
Verifica la firma en el servidor cada vez. Fija el algoritmo de firma (alg) aceptado al valor que esperas y rechaza alg:none (sin firma). No confíes a ciegas en el alg escrito en el encabezado del token.
No pongas secretos en la carga útil
Asume que cualquiera puede decodificar el contenido. Mantén los secretos —contraseñas, datos personales, claves de API— fuera de él. Incluye solo claims que no sean catastróficos si se ven, como identificadores y permisos.
Mantén la expiración corta y ten forma de revocar
Haz que los tokens de acceso sean de vida corta. Una expiración demasiado larga alarga la ventana de daño si uno es robado. Si necesitas revocación, combina un token de acceso de vida corta con un refresh/sesión gestionado en el servidor.
Usa una clave fuerte y guárdala donde no puedan robarla
Haz la clave de firma fuerte, no la reutilices y guárdala en un lugar seguro del servidor. Protege también el token en sí: evita que sea robado vía XSS, llévalo en una cookie con atributos seguros (→ cuidado con el robo vía XSS).
La opinión de este sitio: un JWT no es una sesión multiusos
Los JWT se usan a menudo para "mantener el estado de inicio de sesión", pero tienen una debilidad: la revocación es difícil. Si la firma es válida y no ha expirado, el servidor básicamente confía en él, así que hacer que un cierre de sesión o una invalidación surta efecto de inmediato resulta incómodo. Nuestra postura es: no conviertas un JWT en una sesión multiusos de vida larga. Combina un token de acceso de vida corta con un refresh/sesión revocable en el servidor, y obtienes tanto la ventaja del JWT (verificación barata) como una revocación fácil. Elige el uso adecuado para él.
Punto ciego: "se decodificó" no es "es válido"
Como el contenido es legible, cualquiera puede pegar un JWT en un decodificador de JWT e inspeccionar el encabezado y la carga útil. Pero decodificar (leer el contenido) y verificar (confirmar la autenticidad) son cosas completamente distintas. Poder decodificar no garantiza nada sobre la validez. Lo que decide si un token es genuino es siempre la verificación de la firma en el servidor. Leer el contenido para depurar es práctico: solo no confundas "pude leerlo" con "es válido".
Sigue leyendo
- Herramienta: Decodificador / inspector de JWT (comprueba el contenido, detecta alg:none o la expiración)
- Glosario: qué es XSS (una vía clásica de robo de tokens) / qué es CSRF
- Aprende: elegir bien la MFA
FAQ
Q¿El contenido de un JWT está cifrado?
No. El encabezado y la carga útil de un JWT estándar están 'codificados' con base64url, no cifrados, así que cualquiera que tenga el token puede leer el contenido. Por eso nunca pongas secretos como contraseñas o datos personales en la carga útil. Lo que protege un JWT no es la 'confidencialidad del contenido' sino 'que no haya sido manipulado' (la integridad, vía la firma).
Q¿Cuál es el ajuste más peligroso de un JWT?
No verificar la firma, o aceptar 'alg:none' (sin firma). Permitir eso deja que un atacante pase un token falsificado con el contenido reescrito libremente. La defensa es verificar siempre la firma en el servidor y fijar el algoritmo de firma (alg) aceptado al valor que esperas.
Q¿Decodificar y verificar son lo mismo?
No. Decodificar solo lee el contenido y cualquiera puede hacerlo (puedes comprobarlo con un decodificador de JWT). Verificar es que el servidor confirme, con una clave secreta/pública, que la firma es válida, que el token no ha expirado y que el emisor/audiencia son correctos. 'Se decodificó' no significa 'es un token válido': la verificación en el servidor decide la autenticidad.