Metodología auth / JWT / sesión
Auditar de forma sistemática los mecanismos de autenticación y gestión de sesión — la categoría donde un solo fallo suele dar el impacto más alto (account takeover completo) de todo el programa.
📋 Índice de contenidos
01Objetivo
Auditar de forma sistemática los mecanismos de autenticación y gestión de sesión — la categoría donde un solo fallo suele dar el impacto más alto (account takeover completo) de todo el programa.
02Teoría
Por qué JWT concentra tantos fallos reales
Un JSON Web Token mal entendido por el equipo que lo implementa es una fuente de vulnerabilidades desproporcionadamente alta respecto a lo simple que parece el estándar. Checklist de lo que se prueba siempre:
- Algoritmo
none. Algunas librerías aceptan un token con el campoalgpuesto anoney sin firma, confiando ciegamente en el payload. Prueba siempre reescribir el token conalg: noney firma vacía. - Confusión de algoritmo RS256 → HS256. Si el servidor valida con la clave pública (RS256) pero también acepta HS256, se puede firmar un token falso usando la clave pública (que es, por definición, pública) como secreto HMAC.
- Clave secreta débil o filtrada. Si el token usa HS256, probar claves débiles/por defecto conocidas, y buscar la clave en el recon pasivo (repositorios públicos, módulo 3).
- Validación de expiración y de claims críticos. ¿El servidor realmente rechaza un token expirado, o solo el cliente deja de enviarlo? ¿Se valida el claim
aud/iss, o un token emitido para otro servicio del mismo proveedor de identidad es aceptado aquí? - Qué pasa al modificar claims del payload (rol, id de usuario, scope) sin romper la firma en servidores donde la verificación de firma y la lectura del payload no están correctamente acopladas en el código.
Gestión de sesión más allá de JWT (cookies, sesiones server-side)
- Invalidación real en logout. Cierra sesión y reutiliza el token/cookie anterior: si sigue funcionando, el logout es solo cosmético en el cliente.
- Invalidación tras cambio de contraseña. Cambiar la contraseña debería invalidar todas las sesiones activas anteriores (en todos los dispositivos). Es un fallo habitual que no lo haga.
- Fijación de sesión (session fixation). ¿Se emite un nuevo identificador de sesión tras el login, o se reutiliza el que ya existía antes de autenticarse (permitiendo a un atacante fijar un ID conocido y luego hacerse con la sesión autenticada)?
- Flujos de recuperación de contraseña y verificación de email/2FA como superficie de autenticación propia. El token de reset de contraseña: ¿expira?, ¿es de un solo uso?, ¿es predecible?, ¿se invalida al emitir uno nuevo? El código de 2FA: ¿tiene límite de intentos (si no, es fuerza bruta trivial de 4-6 dígitos)?
La trampa del orden de capas: un error de validación no prueba un bypass de auth
Este es el falso positivo de mayor confianza (y más caro) en toda la categoría de bypass de autenticación, porque la evidencia parece sólida. El razonamiento que falla:
"Mandé una petición sin autenticar y me respondió 400 — el campo X es obligatorio. Un error de validación significa que la petición pasó la autenticación y llegó a la lógica de negocio. Por tanto, falta control de acceso."
Esa inferencia solo es válida si la autenticación se ejecuta antes que la validación de entrada. Muchos backends ponen un sanitizador global, un parser de body o un filtro de esquema delante del middleware de autenticación. Un body malformado se rechaza ahí, antes de que la autenticación llegue a evaluarse siquiera — y la respuesta es indistinguible de "pasó la auth pero falló la validación".
La prueba real: repite la petición con un body mínimo pero bien formado.
# body malformado — dispara el sanitizador, que se ejecuta PRIMERO
curl -s -X POST https://objetivo/api/v1/recurso -d '{'
# → 400 {"code":"ERR-INPUT-0001","message":"Solo se permiten caracteres válidos"}
# (parece un bypass de auth, pero NO lo prueba)
# mismo endpoint, objeto vacío bien formado — ahora sí se alcanza la auth
curl -s -X POST https://objetivo/api/v1/recurso -H 'Content-Type: application/json' -d '{}'
# → 401 {"code":"ERR-AUTH-0001","message":"No autenticado"}Solo la segunda respuesta dice de verdad dónde está la capa de autenticación. El orden de las capas no es observable desde una sola petición: nunca lo infieras de un único resultado. Prueba siempre la autenticación con el body válido más simple que el parser acepte, no con uno malformado — un body malformado solo demuestra que existe un validador, no dónde está la auth respecto a él.
Metodología de prueba paso a paso
- Captura un token/cookie de sesión válido con el proxy.
- Decodifica el JWT (si aplica) y enumera cada claim.
- Para cada punto del checklist anterior, genera la variante manipulada y repite la petición autenticada original con esa variante.
- Documenta qué controles existen (no asumas que porque uno falla, todos fallan — un reporte preciso distingue cuáles de los 5 puntos están realmente rotos).
03Lab asociado
Practica este módulo completo sobre GhostAuth, la app de la serie Ghost dedicada específicamente a tres fallos reales de JWT en un sistema de identidad/notas personales. El objetivo del lab es encontrar los tres fallos de forma independiente, documentando para cada uno qué punto exacto del checklist lo detectó.
04Resumen operativo
- JWT falla más por implementación que por diseño del estándar: prueba
alg: none, confusión RS256/HS256 y claves débiles siempre. - Logout y cambio de contraseña deben invalidar sesiones reales, no solo borrar el token en el cliente.
- Los flujos de recuperación de contraseña y 2FA son superficie de autenticación por derecho propio.
- Un reporte preciso distingue qué control exacto falla, no generaliza "la autenticación es insegura".
- Un error de validación con un body malformado no prueba un bypass de auth: repite siempre con un body mínimo bien formado antes de afirmarlo.