Cheatsheet

Cheatsheet de ataques a jwt

⚠️ Contenido generado por IA (Claude) el 2026-09-06, a partir de conocimiento entrenado — NO es research con fuente verificada en vivo. Casos reales relacionados (falsificación/robo de tokens de sesión, no JWT específicamente, pero mismo principio de fondo): [[2026-09-06-manual-caso-real-microsoft-storm-0558-signing-key-2023|Microsoft/Storm-0558 (2023)]], [[2026-09-06-manual-caso-real-okta-har-files-session-tokens-2023|Okta (2023)]].

Vectores de ataque más comunes contra JWT, en orden de probabilidad real

  1. alg: none: algunas librerías (mal configuradas o viejas) aceptan un token con el header alg en none y sin firma — si el servidor no verifica explícitamente que el algoritmo esperado coincide, el atacante forja cualquier payload sin conocer ningún secreto.
  2. Confusión de algoritmo RS256 → HS256: si el servidor verifica firmas RS256 con la llave PÚBLICA (que cualquiera puede obtener del endpoint JWKS o de la config), un atacante puede forjar un token firmado con HS256 usando esa llave pública como "secreto" HMAC — si el código de verificación no fija el algoritmo esperado, acepta el token forjado como válido.
  3. Secreto HMAC débil o adivinable: si el servidor usa HS256 con un secreto corto o por defecto (secret, nombre del proyecto, etc.), es factible crackearlo offline con hashcat (modo 16500) contra un token capturado.
  4. kid (Key ID) manipulado: si el header kid se usa para seleccionar qué llave verificar sin sanitizar, puede ser vector de path traversal (apuntar a un archivo local conocido como llave) o SQL injection (si el kid se usa en una query sin parametrizar).
  5. JWKS spoofing: si el servidor confía en un jku/x5u (URL del header apuntando a dónde buscar la llave pública) sin validar que sea un dominio propio, el atacante hostea su propio JWKS con su propia llave y firma tokens que el servidor validará como legítimos.
  6. Tokens sin expiración o con expiración larga sin revocación real: un JWT robado (vía XSS, logs, o exactamente como en el caso de Okta con archivos HAR) sigue siendo válido hasta que expira — a diferencia de una sesión de servidor tradicional, no hay forma de "cerrar sesión" del lado servidor sin una blocklist explícita.

Flujo de prueba

  1. Decodificar el JWT (jwt_decode/burp) y revisar el header: algoritmo declarado, presencia de kid/jku/x5u.
  2. Probar alg: none con la firma vacía.
  3. Si es RS256, obtener la llave pública (JWKS endpoint, certificado TLS, config expuesta) y probar confusión de algoritmo firmando un token propio con HS256 usando esa llave pública como secreto.
  4. Si es HS256, intentar crackear el secreto offline contra un token real capturado.
  5. Revisar el mecanismo de logout/revocación: ¿el JWT sigue siendo válido después de "cerrar sesión"? Es un hallazgo real y reportable incluso si ningún ataque de forjado funciona.

Severidad

Cualquier bypass de firma exitoso (alg none, confusión de algoritmo, secreto crackeado) es CRÍTICO por default — equivale a forjar identidad arbitraria sin credenciales, el mismo impacto de fondo que tokens robados/forjados en incidentes reales de gran escala.