Manipulación de JWT: Vulnerabilidades en Tokens Web JSON

Publicado el por Admin

Manipulación de JWT

Los **JSON Web Tokens (JWT)** se han convertido en un estándar popular para la autenticación y la autorización en aplicaciones modernas, especialmente en arquitecturas de microservicios y APIs RESTful. Aunque son potentes y flexibles, una implementación incorrecta de JWT puede abrir la puerta a vulnerabilidades críticas que permiten a los atacantes bypassar la autenticación, escalar privilegios o incluso obtener acceso no autorizado a datos sensibles.


¿Qué es un JWT?

Un JWT es una cadena de texto compacta y URL-segura que se utiliza para transmitir información de forma segura entre dos partes. Está compuesto por tres partes separadas por puntos (`.`):

  1. **Header (Cabecera):** Contiene metadatos sobre el token, como el tipo de token (JWT) y el algoritmo de firma utilizado (ej., HS256, RS256).
    {
      "alg": "HS256",
      "typ": "JWT"
    }
  2. **Payload (Carga Útil):** Contiene las "claims" o afirmaciones sobre el usuario o el token. Estas pueden ser claims registradas (ej., `iss` para emisor, `exp` para expiración), públicas (definidas por el usuario) o privadas (acuerdos entre las partes).
    {
      "sub": "usuario@ejemplo.com",
      "name": "Usuario de Prueba",
      "isAdmin": false,
      "exp": 1678886400
    }
  3. **Signature (Firma):** Se utiliza para verificar que el token no ha sido alterado y que fue emitido por un emisor legítimo. Se calcula codificando la cabecera y la carga útil en Base64url, concatenándolas con un punto, y luego firmando el resultado usando el algoritmo especificado en la cabecera con una clave secreta (para algoritmos simétricos como HS256) o un par de claves (para asimétricos como RS256).

Las tres partes se codifican en Base64url y se unen con puntos para formar el JWT final: `header.payload.signature`.


Vectores Comunes de Manipulación de JWT

1. Vulnerabilidad "None" Algorithm

Algunas librerías JWT históricamente permitían un algoritmo de firma "None", lo que significa que el token no está firmado. Si un servidor no verifica que el algoritmo no sea "None" o no valida la firma, un atacante puede modificar la cabecera a `{"alg": "none", "typ": "JWT"}` y el payload a su gusto, sin necesidad de conocer la clave secreta. El servidor lo aceptará como válido.

// Header Original: {"alg": "HS256", "typ": "JWT"}
// Header Modificado: {"alg": "none", "typ": "JWT"}
// Payload Modificado: {"sub": "admin", "isAdmin": true, "exp": ...}
// Firma: (Vacía o cualquier cosa)

2. Confusión de Algoritmos (RS256 a HS256)

Si un servidor espera un token firmado con un algoritmo asimétrico (RS256, que usa una clave pública para verificar la firma y una privada para firmar) pero también permite algoritmos simétricos (HS256, que usa una única clave secreta para firmar y verificar), un atacante puede engañar al servidor. Si el atacante conoce la clave pública del servidor, puede firmar un token con el algoritmo HS256 utilizando esa clave pública como clave secreta. El servidor, al intentar verificar el token HS256, utilizará la misma "clave pública" como clave secreta y la firma coincidirá.

// Header Original (RS256): {"alg": "RS256", "typ": "JWT"}
// Header Modificado (HS256): {"alg": "HS256", "typ": "JWT"}
// La clave pública utilizada para RS256 ahora se usa como clave secreta para HS256.

3. Clave Secreta Débil

Para tokens HS256, si la clave secreta utilizada para firmar el token es débil, un atacante puede recuperarla mediante ataques de fuerza bruta o diccionario. Una vez que tienen la clave, pueden crear y firmar tokens válidos con cualquier payload.

// Herramientas como hashcat pueden usarse para crackear la firma si la clave es débil.

4. Inyección de Key ID (`kid`)

El parámetro `kid` (key ID) en la cabecera JWT puede ser utilizado para que el servidor busque la clave de verificación en una ubicación específica (ej., un archivo local, una URL). Si no se valida correctamente, un atacante podría:

{
  "alg": "HS256",
  "typ": "JWT",
  "kid": "../../etc/passwd" // Intentando leer el archivo de contraseñas
}

5. Falta de Validación de Claims

La aplicación puede no validar las claims importantes en el payload, como:


Impacto de la Manipulación de JWT

Una manipulación exitosa de JWT puede llevar a:


Prevención de la Manipulación de JWT

La seguridad de JWT reside en una implementación correcta y en la validación estricta de todos sus componentes:

  1. **Siempre Validar la Firma:**

    Nunca confíes en el algoritmo `alg` proporcionado en el header. La aplicación debe validar la firma utilizando el algoritmo que se espera que se use para ese token específico y la clave secreta/pública correcta.

    // Pseudocódigo (nunca permitir 'none' explícitamente)
    if (token.header.alg == "none") {
        reject_token();
    }
    // Validar firma usando la clave esperada y el algoritmo esperado
  2. **Usar Claves Secretas Fuertes y Únicas:**

    Para algoritmos simétricos (HS256), utiliza claves secretas criptográficamente fuertes y únicas para cada servicio. Rotar estas claves periódicamente.

  3. **Gestión Segura de Claves (RS256):**

    Para algoritmos asimétricos, almacena la clave privada de forma segura y solo expón la clave pública. No permitir que la clave pública sea cargada desde ubicaciones arbitrarias basadas en la entrada del usuario (`kid`).

  4. **Validar Todas las Claims Cruciales:**

    Además de la firma, la aplicación debe validar las claims como `exp` (expiración), `nbf` (not before), `aud` (audiencia) e `iss` (emisor) para asegurar que el token es válido en el tiempo y el contexto previsto. Si el rol del usuario está en el payload (`isAdmin`), verificarlo también contra la base de datos.

  5. **Evitar Información Sensible en el Payload:**

    Por defecto, el payload de un JWT no está cifrado, solo codificado en Base64url. No almacenes información sensible (contraseñas, datos personales) en el payload a menos que uses JWE (JSON Web Encryption) para cifrarlo.

  6. **Implementar Revocación de Tokens (si es necesario):**

    Aunque los JWT son "stateless" (sin estado), para casos donde la revocación inmediata es crucial (ej. cambio de contraseña, cierre de sesión forzado), considera mecanismos como listas negras o tokens de corta duración con tokens de refresco.

  7. **Utilizar Librerías JWT Actualizadas:**

    Confía en librerías JWT bien mantenidas y actualizadas. Evita implementar tu propia lógica de JWT a menos que seas un experto en criptografía.


Consideraciones Éticas

Este artículo tiene fines educativos y de concienciación sobre la ciberseguridad. Intentar manipular o explotar JWT en sistemas ajenos sin la autorización expresa del propietario es ilegal y puede tener graves consecuencias legales. Utiliza estos conocimientos de forma responsable y ética, siempre en entornos de prueba controlados y autorizados.

¿Qué otras defensas contra la manipulación de JWT consideras importantes? ¡Comparte tu conocimiento en los comentarios!

La implementación segura de JWT es fundamental para la seguridad de cualquier aplicación moderna que los utilice como método de autenticación y autorización.