⚠️ 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
alg: none: algunas librerías (mal configuradas o viejas) aceptan un token con el headeralgennoney sin firma — si el servidor no verifica explícitamente que el algoritmo esperado coincide, el atacante forja cualquier payload sin conocer ningún secreto.- 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.
- 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 conhashcat(modo 16500) contra un token capturado. kid(Key ID) manipulado: si el headerkidse 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 elkidse usa en una query sin parametrizar).- 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. - 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
- Decodificar el JWT (
jwt_decode/burp) y revisar el header: algoritmo declarado, presencia dekid/jku/x5u. - Probar
alg: nonecon la firma vacía. - 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.
- Si es HS256, intentar crackear el secreto offline contra un token real capturado.
- 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.