JWT desde 0

Carol12Gory - Oasis
8 min readMay 17, 2023

--

3,2,1 … Empezamos!

Primera entrada técnica del blog y qué mejora manera de empezar que con los conceptos básicos de JWT.

Espero que os sirva tanto como me ha servido a mi para entender más que es JWT.

  1. Introducción a autenticación y JWTs

2. Estructura de JWTs

3. Firma de un token JWT

4. Securización de Token JWT

5. Ciclo de vida de un Token JWT

6. Understanding HS256

7. Understanding RS256

8. Recomendaciones para evitar ataques a JWT

9. Referencias

1. Introducción a JWTs

JSON Web Token (JWT) es un estándar abierto (RFC 7519) que define una forma compacta y autónoma de transmitir información de forma segura entre las partes como un objeto JSON. Esta información puede ser verificada y confiable porque está firmada digitalmente. Los JWT pueden ser firmados usando un secreto (con el algoritmo HMAC) o un par de claves públicas/privadas usando RSA o ECDSA.

JWT se utiliza para autorizar al usuario, una vez logueado, a acceder a las rutas, servicios y recursos que se permiten con ese token a los usuarios en las aplicaciones después de un inicio de sesión válido y también para transmitir información de forma segura entre las partes

Éstos se basan en el formato JSON e incluyen una firma para asegurar la integridad del token.

2. Estructura de JWTs

Se trata de una cadena de texto formada por tres partes codificadas en Base64, donde cada una de ellas está separada por un punto, como se observa en la siguiente imagen:

Estructura JWT

Este token puede ser decodificado y mostraría la siguiente apariencia con diferentes Claims (propiedades):

El token está formado por tres partes: header, payload y signature.

Header, payload y signature

Header

La primera parte «header«, hace referencia al encabezado dónde se indica, al menos, el algoritmo (alg) y el tipo de token (typ).

En la imagen, correspondería a la siguiente cadena «eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9»

Header

Existen varios tipos de algoritmo como HS256 y RS256:

  • HS256: Simétrico, usa el mismo «secret» para firmar y para verificar el token. Es más seguro (siempre y cuando el «secret» no se vea comprometido y sea robusto) , más rápido y el token es más pequeño.
  • RS256: Asimétrico (un par de claves públicas/privadas), usa una clave privada para firmar el token y usa una clave pública para verificar el token.

Se puede emplear HS256 de forma segura, ya que se tiene el control sobre quién usa las claves secretas. En el caso de que no se tenga control sobre el cliente o si no se tiene forma de asegurar la «shared key», es mejor emplear RS256 ya que el consumidor solo necesita conocer la clave pública (compartida).

Payload

La segunda parte «payload«, hace referencia a los datos de usuario y privilegios de éste. Existen 3 tipos de Claims:

- Public Claim Names: son valores personalizados públicos. Para evitar colisiones, se recomienda registrarlos en IANA JSON Web Token Registry.

- Private Claim Names: son valores personalizados privados. Estos pueden estar sujetos a colisiones.

- Registered Claim Names: son valores acerca del registro. Estos proporcionan información acerca del contenido. Existen varios tipos de de Claim específicos:

  • iss: Identifica al emisor del token. El uso de este claim es opcional.
  • sub: Identifica el asunto del JWT. El valor del sujeto debe ser contemplado para ser locamente único en el contexto del emisor o ser globalmente único. El uso de este claim es opcional.
  • aud: Identifica a los receptores del JWT. El uso de este claim es opcional.
  • exp: Identifica la hora de expiración, a partir de la cual, el token no será válido para su procesamiento. El uso de este claim es opcional.
  • nbf: Identifica el momento antes del cual el JWT no debe ser aceptado para su procesamiento. Requiere que la fecha/hora actual debe ser posterior o igual a la fecha/hora que figura en ‘nbf’. El uso de este claim es opcional.
  • iat: Identifica la hora a la que fue emitido el token. El uso de este claim es opcional.
  • jti: Identifica un ID único para el JWT. Este debe asignarse de manera que asegure que hay una probabilidad insignificante de que el mismo valor sea asignado accidentalmente a un objeto de datos diferente; si la aplicación utiliza múltiples emisores, se deben prevenir las colisiones entre los valores producido por diferentes emisores también. El uso de este claim es opcional.

En la imagen, correspondería a la siguiente cadena «eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ»

Payload

Signature

Por último, la tercera parte «signature», permite verificar si el token es válido. En la imagen, correspondería a la siguiente cadena «SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c»

3. Firma de un token JWT

La firma de un token JWT garantiza la validez del mensaje y de remitente.

La firma se construye como el HMACSHA256, que son las siglas de Hash-Based Message Authentication Code (Código de Autenticación de Mensajes), cifrado con el algoritmo SHA de 256. Esta función es aplicada a:

  • Codificación en Base64 de header
  • Codificación en Base64 de payload
  • Un secreto (establecido por la aplicación)
Firma de un JWT

La firma se genera, en primer lugar, cuando la aplicación concatena la cadena de «header» y «payload» en Base64url. Después, se usa el secreto y se aplica el algoritmo presente en «header» para generar la «signature».

Todo este proceso no garantiza que el Token JWT sea completamente seguro.

Con las medidas mencionadas, en el caso de que se trate de modificar algún dato, se podría verificar la integridad del mensaje y denegar la solicitud de datos que hayan sido solicitados. Siempre se debería de verificar con esta firma si el token es válido.

4. Securización de Token JWT

Es necesario tener en cuenta la securización del token debido a que los datos de «header» y «payload» se codifican en Base64url y con lo cual, no van cifrados sino codificados.

Se recomienda que la comunicación entre el cliente y el servidor vaya cifrada con el protocolo HTTPS.

5. Ciclo de vida de un Token JWT

A continuación, se explica el ciclo de vida de un Token JWT.

En primer lugar, el cliente hace una petición POST al servidor enviando el usuario y contraseña. De esta manera, se realiza el proceso de login.

A continuación, en el servidor se comprueba que el usuario y contraseña son correctos, y si lo son, se genera un token JWT que es enviado al cliente.

A partir de ese momento, la aplicación cliente, con el token generado, hace peticiones al cliente solicitando recursos. Este token JWT siempre va en las cabeceras de las peticiones; se mostraría de la siguiente forma «Authorization: Bearer XXXXXXX», siendo Bearer el prefijo que precede al contenido del token.

En la parte del servidor, se comprueba la validez del token mediante la firma para verificar que el token es válido.

Una vez verificado el token e identificado al usuario que ha realizado la petición, se aplica el control de acceso a los recursos que solicite.

Ciclo de vida de un token JWT

6. Understanding HS256

HS256 es un algoritmo de firma SHA256 que codifica «Header»,«Payload» y «Secret» en base64url.

HS256

En primer lugar, se mandan las credenciales del login desde «Client» a «Authorization Server» y este comprueba si las credenciales son válidas.

En el caso de que las credenciales sean válidas, «secret key» es empleada para la generación de un token JWT válido. (Esa «secret key» es distribuida a los diferentes «Resource Server» presentes en la aplicación).

Una vez que «Client» tiene el token JWT válido e intenta acceder a «Resource Server» este comprueba que la «secret key» con la que se ha firmado el token JWT es la misma que el posee.

Un ataque no tendría acceso a «Resource Server» debido a que, en primer lugar, comprueba la existencia de un token JWT válido. Para poder obtener «secret key» tendría que darse alguna de las siguientes casuísticas:

Dado que «secret key» es distribuida a todos los servidores, si se compromete un servidor, se podría obtener dicha «secret key».

Si el «Header» de «secret key» que se emplea con HS256 es débil, ésta puede ser obtenida a través de fuerza bruta.

7. Understanding RS256

RS256 es la «signature» del hash generado a partir del «Header» y del «Payload». Dicho hash se firma utilizando la clave privada de RSA. Esta firma generada es la tercera parte del JWT.

RS256

RS256 usa algoritmos de cifrado RSA y SHA256.

Solamente se puede emplear este tipo de firma si se tiene la «secret key» para descifrar el hash generado. Esta «secret key» solamente se encuentra disponible en «Authorization Server», que es donde se generan los token JWT y no se encuentra disponible en ningún «Resource Server».

En primer lugar, se mandan las credenciales del login desde «Client» a «Authorization Server» y este comprueba si las credenciales son válidas.

En el caso de que las credenciales sean válidas, «secret key» es empleada para la generación de un token JWT válido.

Una vez obtenido un token JWT válido, cuando se quiera acceder a «Resource Server», este tiene que comprobar si la «signature» del JWT es válido o no. Usa la «public key» (presente en los «Resource Server») para validar si la «signature» presente en el JWT es válida o no.

Si el atacante quiere acceder a «Resource Server» no podrá acceder debido a que no tiene un token JWT válido. Para poder acceder a «Resource Server», el atacante debe tener las credenciales del login y un token JWT válido o tener acceso a «secret key», habiendo comprometido previamente «Authoriztion Server» que es donde se localiza «secret key», para generarse sus propios tokens JWT válidos.

El empleo de RS256 implica:

«Private key» solamente está presente en «Authorization Server».

Solamente aquel servidor que tenga la «private key» puede crear nuevos tokens JWT válidos.

El empleo de cifrados de tipos RSA son lo suficientemente largos para prevenir los ataques de fuerza bruta.

8. Recomendaciones para evitar ataques a JWT

No se recomienda el uso del algoritmo ‘none’ en la generación de **JWT**.

Se recomienda el uso de claves compartidas robustas para evitar, de esta forma, que sea fácil crackear esta clave.

Se recomienda establecer siempre una fecha de caducidad para los tokens que se emitan y que estos no sean válidos una vez se cierre sesión.

Se recomienda el uso de un algoritmo en vez de una whitelist donde permita, por ejemplo, el algoritmo ‘none’. En el caso de que se necesite emplear algoritmos como RS256 y HS256, se recomienda que se separen ambos algoritmos en funciones diferentes para tener un control sobre las claves que se emplean en cada caso.

Se recomienda que se añada el claim aud (audiencia) (o similar) para especificar el destinatario del token. Esto evita que se utilice en diferentes sitios web.

9. Referencias

En futuras publicaciones se pondrá en práctica todo lo aprendido en diferentes ejercicios relacionados con JWT.

Nos vemos en el próximo! 😊

--

--

Carol12Gory - Oasis

Offensive Security Engineer en Telefónica Tech. Co-autora del libro Social Hunters: Hacking con ingeniería social en el Red Team. carol12gory.com | @Carol12Gory