JWT
2 tools
Fundamentos de seguridad web
La seguridad web es la práctica de proteger aplicaciones web y APIs del acceso no autorizado, las brechas de datos y los ataques. Las aplicaciones modernas usan autenticación, autorización y criptografía para hacer cumplir los límites de seguridad.
Los JSON Web Tokens (JWT) son el mecanismo de autenticación sin estado dominante en el desarrollo web moderno. Entender cómo funcionan los JWT — incluyendo su estructura, algoritmos de firma y vulnerabilidades — es esencial para construir APIs y aplicaciones seguras.
JSON Web Tokens (JWT)
Un JWT es una forma compacta y segura para URLs de representar afirmaciones entre dos partes. Consta de tres partes codificadas en Base64url separadas por puntos. Los JWT pueden verificarse sin consultas a bases de datos porque la firma cubre todo el token.
Las tres partes de un JWT
Contiene metadatos sobre el token: el algoritmo de firma (alg) y el tipo de token (typ). Siempre JSON codificado en Base64url. La elección del algoritmo aquí afecta la seguridad de todo el token.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9{
"alg": "HS256",
"typ": "JWT"
}Contiene las afirmaciones: declaraciones sobre el usuario y metadatos adicionales. También JSON codificado en Base64url. Cualquiera puede decodificar esto — los datos del payload NO están cifrados, solo firmados.
eyJzdWIiOiJ1c2VyXzEyMyIsInJvbGUiOiJhZG1pbiIsImV4cCI6MTcxNzIwMDAwMH0{
"sub": "user_123",
"role": "admin",
"exp": 1717200000
}Una firma criptográfica sobre el encabezado y el payload codificados. Verificar esta firma garantiza que el token no fue alterado. La clave secreta (HMAC) o la clave privada (RSA/ECDSA) nunca se incluye en el token.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5cHMACSHA256( base64url(header) + "." + base64url(payload), secret )
Afirmaciones JWT estándar
La especificación JWT define nombres de afirmaciones estándar. Usarlos garantiza la interoperabilidad entre diferentes bibliotecas y servicios JWT:
| Afirmación | Nombre | Descripción |
|---|---|---|
| iss | Issuer | Identifica al principal que emitió el token (ej. URL de tu servidor de autenticación) |
| sub | Subject | Identifica al principal que es el sujeto del token (ej. ID de usuario) |
| aud | Audience | Identifica a los destinatarios para los que está destinado el token (ej. URL de tu API) |
| exp | Expiration | Timestamp Unix después del cual el token no debe aceptarse para su procesamiento |
| nbf | Not Before | Timestamp Unix antes del cual el token no debe aceptarse para su procesamiento |
| iat | Issued At | Timestamp Unix en el que se emitió el token — usado para determinar su antigüedad |
| jti | JWT ID | Identificador único para el token, usado para prevenir ataques de repetición de tokens |
Algoritmos de firma
El algoritmo de firma se declara en el encabezado JWT. Elegir el algoritmo correcto para tu caso de uso es crítico para la seguridad:
HS256 / HS384 / HS512Simétrico (HMAC)Usa una clave secreta compartida para firmar y verificar. Simple de implementar pero requiere que todos los verificadores conozcan el secreto.
RS256 / RS384 / RS512Asimétrico (RSA)Usa una clave privada para firmar y una clave pública para verificar. La clave privada nunca sale del servidor de autenticación.
ES256 / ES384 / ES512Asimétrico (ECDSA)Como RSA pero con claves más pequeñas y firma más rápida. Proporciona seguridad equivalente con mejor rendimiento.
"alg": "none"Sin firmar — PELIGROSOSin firma alguna. Un token con alg:none no tiene garantía de integridad y puede ser falsificado por cualquiera.
Flujos de autenticación
- 1.El usuario envía nombre de usuario y contraseña al endpoint de inicio de sesión
- 2.El servidor valida las credenciales contra la base de datos de usuarios
- 3.El servidor firma un JWT con las afirmaciones del usuario y la expiración
- 4.El cliente almacena el JWT (localStorage, cookie o memoria)
- 5.El cliente envía el JWT en el encabezado Authorization: Bearer para las solicitudes posteriores
- 1.El cliente redirige al usuario al servidor de autorización con el desafío de código
- 2.El usuario se autentica y autoriza la aplicación cliente
- 3.El servidor de autenticación redirige de vuelta con un código de autorización de un solo uso
- 4.El cliente intercambia el código + verificador por tokens de acceso y actualización
- 5.El cliente usa el token de acceso para llamadas a la API; el token de actualización para renovación
Vulnerabilidades JWT comunes
Los JWT son seguros cuando se implementan correctamente. Estos son los errores de implementación más comunes que conducen a vulnerabilidades de seguridad:
Algunas bibliotecas aceptan tokens con alg:none (sin firma). Un atacante puede modificar el payload y establecer alg en none para falsificar cualquier JWT. Siempre especifica y valida explícitamente el algoritmo permitido.
Si una biblioteca espera verificar RS256 pero acepta HS256, un atacante puede firmar un token usando la clave pública como secreto HMAC. Siempre fija el algoritmo esperado.
Un JWT sin reclamación exp, o código que no verifica exp, permite que los tokens se usen indefinidamente. Siempre establece tiempos de expiración cortos y valida la reclamación exp.
Los payloads JWT están codificados en Base64, no cifrados. Nunca almacenes contraseñas, números de tarjetas de crédito u otros secretos en las afirmaciones JWT.
Los JWT firmados con HMAC con secretos cortos o predecibles pueden ser forzados brutos sin conexión. Usa secretos aleatorios criptográficamente de al menos 256 bits.
Aceptar JWTs sin verificar la firma confía completamente en el payload. Siempre verifica la firma antes de confiar en cualquier afirmación.
Preguntas frecuentes
Los JWT estándar (JWS) están firmados pero NO cifrados. El payload está codificado en Base64url, que es trivialmente reversible. JWE (JSON Web Encryption) proporciona cifrado pero es mucho menos común.
Los tokens de acceso deben ser de corta duración: de 5 a 60 minutos es típico. Usa tokens de actualización (de mayor duración, almacenados de forma segura) para obtener nuevos tokens de acceso.
Las cookies HttpOnly son la opción más segura — son inaccesibles para JavaScript, previniendo el robo por XSS. localStorage es vulnerable a XSS pero evita CSRF. No hay opción perfecta.
No sin estado del lado del servidor. Soluciones: tiempos de expiración cortos, una lista de bloqueo de tokens (Redis) o tokens de sesión opacos para operaciones sensibles.
Las cookies de sesión almacenan un ID de sesión aleatorio; el servidor busca los datos de sesión. Los JWT son autónomos — el servidor valida la firma sin una consulta a la base de datos.
El mínimo: sub (ID de usuario), exp (expiración) e iat (emitido en). Agrega iss (emisor) para configuraciones multi-servicio. Mantén los payloads pequeños.
RS256 (asimétrico) es mejor para la mayoría de los sistemas de producción porque solo el servidor de autenticación necesita la clave privada. Múltiples servicios pueden verificar tokens usando la clave pública.
PKCE (Proof Key for Code Exchange) es una extensión del flujo de código de autorización OAuth2 que previene los ataques de interceptación de código de autorización. Es obligatorio para clientes públicos (SPAs, aplicaciones móviles).