Seguridad · 4 min de lectura ·

Qué hay dentro de un JWT y por qué decodificar no es verificar

Un JSON Web Token parece una cadena aleatoria, pero cualquiera puede leerlo. Qué contienen sus tres partes y el error que abre agujeros de seguridad.

Un JWT (JSON Web Token) es la cadena larga que mantiene tu sesión abierta en muchas aplicaciones web y API. Parece cifrado, pero en la mayoría de los casos no lo está: cualquiera que tenga el token puede leer lo que contiene.

Tres partes separadas por puntos

eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI0MiJ9.3q2-7w…
└ header ──────────┘ └ payload ───────┘ └ signature

El header indica cómo se firma el token, por ejemplo HS256 o RS256. El payload guarda los claims: quién es el usuario (sub), cuándo se emitió el token (iat) y cuándo caduca (exp), además de lo que añada la aplicación, como los roles. Ambos son JSON codificado en base64url, que es una codificación, no un cifrado.

Lo que importa es la firma

La tercera parte es una firma sobre las dos primeras, hecha con un secreto o una clave privada. Solo un servidor con la clave correcta puede comprobarla. Si alguien cambia un solo carácter del payload, por ejemplo el rol de user a admin, la firma deja de coincidir.

Decodificar no es verificar

Un token que se decodifica bien te dice lo que afirma, no si es verdad. Tu backend debe verificar la firma con la clave, rechazar los tokens cuyo exp ya pasó y aceptar solo los algoritmos que espera, nunca «none». Las bibliotecas JWT lo hacen por ti; saltárselo es una vulnerabilidad clásica.

Reglas prácticas

No pongas secretos como contraseñas en el payload, porque se puede leer. Usa tiempos de caducidad cortos. Trata un token como una contraseña mientras sea válido: quien lo copie puede usarlo hasta que caduque.

Dónde guardar un token en el navegador

Cualquier script de la página puede leer lo que se guarda en localStorage, así que un solo fallo de cross-site scripting (XSS) puede filtrar el token. Una cookie HttpOnly no es accesible desde JavaScript, lo que elimina ese riesgo; combínala con los atributos Secure y SameSite y con protección contra la falsificación de peticiones entre sitios (CSRF). No hay una opción perfecta, pero para tokens de sesión las cookies HttpOnly son la opción más segura por defecto.

Caducidad y tokens de actualización

Un JWT no se puede «cerrar» por sí solo: sigue siendo válido hasta su exp, salvo que el servidor mantenga una lista de revocación. Por eso los tokens de acceso suelen durar minutos, no días. Un token de actualización de mayor duración, guardado con más cuidado y comprobado en el servidor, sirve para obtener un nuevo token de acceso cuando el anterior caduca.

Los claims habituales de un vistazo

iss  emisor        quién creó el token
sub  sujeto        el usuario o cliente al que se refiere
aud  audiencia     qué servicio debe aceptarlo
exp  caducidad     hora Unix a partir de la cual no es válido
nbf  no antes de   hora Unix antes de la cual no es válido
iat  emitido en    hora Unix en que se creó

Los claims de tiempo son marcas de tiempo Unix en segundos. El servidor debe comprobar aud además de exp: un token válido emitido para un servicio no debería aceptarse en otro.

Leer un token

El decodificador de JWT de 4Dev separa un token en sus partes y muestra el header y el payload como JSON legible. Solo decodifica y no comprueba la firma. El token se envía al servidor de 4Dev para decodificarlo y no se registra ni se guarda, pero evita pegar tokens reales de producción y revoca cualquier token que creas expuesto.

Abrir el decodificador de JWT

LinkedInXFacebook