¿Cómo funcionan los JWT y qué errores de seguridad debes vigilar?
Respuesta breve
Un JWT tiene tres partes en base64url —cabecera, carga útil (reclamaciones) y firma— unidas por puntos. El servidor firma la cabecera y la carga útil con un secreto o una clave privada, y verifica esa firma en cada solicitud para confiar en las reclamaciones sin estado de sesión en el servidor. Errores: aceptar alg=none, la confusión de claves de RS256 a HS256, no validar expiración/emisor/audiencia, poner secretos en la carga útil legible, y la falta de una vía de revocación.
Los JWT aparecen constantemente en las entrevistas de appsec porque son fáciles de usar y fáciles de usar mal. El entrevistador quiere confirmar que sabes que están firmados, no cifrados, y que puedes nombrar las trampas clásicas de implementación.
Cómo se estructura un JWT
Un JWT tiene tres partes codificadas en base64url separadas por puntos: una cabecera (algoritmo y tipo de token), una carga útil de reclamaciones (sujeto, expiración, emisor, audiencia, roles) y una firma. El servidor crea la firma sobre la cabecera y la carga útil usando un secreto compartido (HS256) o una clave privada (RS256). En cada solicitud recalcula/verifica esa firma; si es válida, se puede confiar en las reclamaciones sin una búsqueda de sesión en el servidor. Esa ausencia de estado es el atractivo, y la fuente de la mayoría de los problemas.
Los errores
alg=none. Algunas bibliotecas históricamente honraban una cabecera que declaraba «sin firma», dejando que un atacante eliminara la firma y falsificara cualquier reclamación. Fija siempre el algoritmo esperado en el servidor en lugar de confiar en la cabecera.- Confusión de claves (RS256 → HS256). Si el servidor usa la clave pública RSA como secreto HMAC, un atacante puede firmar un token falsificado con esa clave pública. Rechaza el cambio de algoritmo.
- Falta de validación de reclamaciones. Una firma solo prueba que el token no fue manipulado: aún debes comprobar la expiración (
exp), el emisor (iss) y la audiencia (aud). Los tokens sin expiración viven para siempre. - Tratarlo como confidencial. La carga útil es solo base64, totalmente legible. Nunca pongas secretos en ella.
- Sin revocación. Como los JWT son sin estado, un token robado es válido hasta que expira. Usa vidas cortas con tokens de refresco, o una lista de denegación para emergencias.
Qué buscan los entrevistadores
La estructura cabecera/carga útil/firma, «firmado no cifrado», la fijación explícita del algoritmo para eliminar alg=none y la confusión de claves, validar exp/iss/aud, y la conciencia de que la revocación es la parte difícil de los tokens sin estado.
Posibles preguntas de seguimiento
- ¿Por qué es tan peligrosa la vulnerabilidad alg=none y cómo se previene?
- ¿Cómo permite la confusión de claves de RS256 a HS256 que un atacante falsifique tokens?
- ¿Cómo se revoca un JWT sin estado antes de que expire?