Utilo

Cómo funciona JWT y cómo decodificar un token de forma segura

Comprender la estructura de los tokens web JSON, cómo se crean y verifican las firmas, las reclamaciones comunes, los fallos de seguridad y cómo decodificar un JWT.

· 6 min de lectura

Los tokens web JSON (JWTs) están en todas partes: inicios de sesión OAuth y OpenID Connect, pasarelas API, inicio de sesión único entre microservicios y sesiones de aplicaciones móviles. También son ampliamente incomprendidas. Los desarrolladores decodifican un token, ven un JSON legible y se preguntan si eso es un problema de seguridad; otros almacenan datos confidenciales en tokens, asumiendo que están cifrados. Este artículo explica exactamente qué es un JWT, cómo se valida y cómo inspeccionarlo sin crear riesgos.

Las tres partes de un JWT

Un JWT parece tres cuerdas aleatorias unidas por puntos:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0MiIsImV4cCI6MTkwMDAwMDAwMH0.Kx8...

Cada parte está codificada con Base64URL:

  1. Cabeza JSON que describe el tipo de token y el algoritmo de firma, por ejemplo {"alg":"HS256","typ":"JWT"}.
  2. ** Payload** JSON que contiene afirmaciones: declaraciones sobre el usuario y el token, como {"sub":"42","exp":1900000000}.
  3. ** Firma ** bytes calculados desde el encabezado y la carga útil con una clave secreta o privada.

Base64URL es una variante de [Base64] ((/blog/base64-explicado) que utiliza - y _ en lugar de + y / y elimina el relleno, por lo que los tokens se pueden colocar en URL y encabezados sin escapar.

Crucialmente, el encabezado y la carga útil sólo están codificados, no cifrados. Cualquiera que tenga la ficha puede leerlas. Pegar un token en un JWT decodificador y la carga útil aparece instantáneamente que es por diseño.

Cómo funciona la firma

La firma es lo que hace que un JWT sea confiable. El emisor toma el encabezado codificado y la carga útil, los une con un punto, y firma esa cadena.

Con HS256 (HMAC con SHA-256), el emisor y el verificador comparten una clave secreta:

signature = HMAC-SHA256(secret, base64url(header) + "." + base64url(payload))

Con RS256 o ES256, el emisor firma con una clave privada y cualquiera puede verificar con la clave pública correspondiente, a menudo publicada en un punto final JWKS como https://login.example.com/.well-known/jwks.json. Los algoritmos asimétricos se prefieren cuando muchos servicios necesitan verificar tokens pero solo uno debe emitirlos.

Cuando un servidor recibe un token, vuelve a calcular o verifica la firma. Si incluso un carácter de la carga útil cambió digamos que un atacante editó "role":"user" a "role":"admin" la firma ya no coincide y el token es rechazado.

Reclamaciones registradas que usted debe saber

La especificación JWT (RFC 7519) define los nombres de las reivindicaciones estándar:

  • iss (emitente): quién creó el token, por ejemplo https://login.example.com.
  • sub (sujeto): de quién se trata el token, generalmente una ID de usuario.
  • aud (audiencia): para quién está destinado el token, como api.example.com.
  • exp (expiración): el tiempo después del cual el token debe ser rechazado, en [segundos Unix] ((/blog/unix-timestamp-explained).
  • nbf (no antes): el tiempo antes del cual el token no es válido.
  • iat (emitido en): cuando se creó el token.
  • jti (ID JWT): un identificador único, útil para las listas de revocación.

Las solicitudes añaden sus propias reivindicaciones: scope, roles, tenant_id, email. Manténgalos pocos, cada reclamo viaja con cada petición.

Validación correcta de un token

Un servidor debe comprobar todo lo siguiente, en este orden:

  1. El algoritmo es el que espera. Configure una lista de permisos como ["RS256"]. Nunca deje que el encabezado del token decida libremente; las vulnerabilidades históricas permiten a los atacantes cambiar a none o engañar a los servidores para que usen una clave pública como un secreto HMAC.
  2. La firma es válida con la clave correcta, elegida por kid de su conjunto de claves de confianza.
  3. exp está en el futuro y nbf está en el pasado, lo que permite un pequeño sesgo del reloj de 3060 segundos.
  4. iss coincide exactamente con su proveedor de identidad.
  5. aud contiene el identificador de su servicio, por lo que un token emitido para otra API no se puede reproducir contra el suyo.

Utilice una biblioteca mantenida jose para JavaScript, PyJWT para Python, golang-jwt para Go en lugar de escribir la verificación usted mismo.

Decodificación versus verificación

Decodificación significa Base64URL-decodificación de las dos primeras partes y análisis del JSON. No requiere llave y no prueba nada sobre la autenticidad. Es útil para:

  • Debugging por qué una API devuelve 401: ¿aud es correcto? ¿Ha expirado la ficha?
  • Verificar qué ámbitos o funciones se conceden en un flujo de inicio de sesión.
  • Confirmando que una actualización de token produjo un nuevo exp.

Verificación significa comprobar la firma y las reivindicaciones según lo descrito anteriormente. Solo los servidores deben tomar decisiones de autorización, y solo después de verificar.

El código front-end puede decodificar un token para mostrar el nombre del usuario o programar una actualización antes de exp, pero nunca debe depender de afirmaciones decodificadas para la seguridad, porque un usuario puede modificar cualquier cosa que se ejecute en su navegador.

Dónde almacenar fichas en el navegador

No hay una respuesta perfecta, sólo compensaciones:

  • ** Las cookies HTTPOnly, Secure, SameSite** no pueden ser leídas por JavaScript, que protege contra el robo de tokens a través de scripts entre sitios. Requieren protección CSRF, aunque SameSite=Lax o Strict cubre la mayoría de los casos.
  • Memoria (una variable JavaScript) está a salvo de la persistencia pero se pierde en la recarga; combínalo con un token de actualización en una cookie HttpOnly.
  • localStorage es conveniente pero legible por cualquier script en la página, por lo que una sola vulnerabilidad XSS filtra cada token.

Para la mayoría de las aplicaciones web, los tokens de acceso de corta duración en la memoria más un token de actualización en una cookie HttpOnly es un buen equilibrio.

Expirar y revocar

Los JWT no tienen estado: un servidor puede validarlos sin una búsqueda de base de datos. La otra cara es que un token válido no se puede revocar fácilmente antes de que expire. Mitigantes:

  • Mantener las fichas de acceso de corta duración 5 a 15 minutos es común.
  • Utilice fichas de actualización, almacenadas de forma segura y verificadas con una base de datos, para emitir nuevas fichas de acceso.
  • Para las acciones de alto riesgo, compruebe una lista de revocación de valores jti o una marca de tiempo de "tokens válidos después" por usuario.

Errores comunes

  • Poner secretos en la carga útil. Las contraseñas, claves de API y datos personales son legibles por cualquier persona con el token. Si necesita confidencialidad, use JWE (tokens cifrados) o guarde los datos en el lado del servidor.
  • Fichas muy duraderas. Una ficha robada que es válida por un año es una violación de un año.
  • Saltando las verificaciones de audiencia. Sin la validación aud, un token para un servicio de bajo privilegio puede usarse contra uno de alto privilegio.
  • Secretos débiles HMAC. Los secretos HS256 deben ser largos y aleatorios al menos 256 bits. Los secretos cortos pueden ser forzados fuera de línea con una sola ficha.
  • ** Logging tokens.** Los registros de acceso y los rastreadores de errores a menudo capturan encabezados Authorization. Redactelas.

Inspeccionando una ficha de forma segura

Al depurar, use un decodificador que se ejecute localmente en su navegador para que el token nunca se envíe a un tercero. Prefiera tokens expirados o de entorno de prueba al compartir capturas de pantalla o pegar en tickets. - ¿ Qué pasa ?

  • alg y kid en la cabecera coinciden con la configuración de su proveedor.
  • iss y aud coinciden con lo que su API espera.
  • exp, iat y nbf tienen sentido en relación con el tiempo actual.
  • Los ámbitos y funciones contienen lo que requiere la operación.

Resumen

Un JWT es un paquete firmado, no cifrado, de reclamos JSON. Su seguridad proviene completamente de la verificación de la firma y la validación de reclamos en el servidor. La decodificación es inofensiva y útil para la depuración; confiar en los datos decodificados sin verificación es el riesgo real. Mantenga las fichas de corta duración, mantenga las cargas útiles pequeñas y libres de secretos, valide el algoritmo, la firma, el vencimiento, el emisor y la audiencia cada vez, e inspeccione las fichas con herramientas que las mantengan en su máquina.

Esta página se tradujo automáticamente del inglés. Si encuentras un error, avísanos.

Guías relacionadas