Ataque JWT (JSON Web Token)
Un ataque JWT explota vulnerabilidades en la implementación de JSON Web Token para evadir la autenticación, escalar privilegios o suplantar usuarios. Los ataques comunes incluyen confusión de algoritmos (configurar 'alg': 'none'), verificación débil de firmas, manipulación de tokens y explotación de la reutilización de tokens entre servicios. Los JWTs se usan ampliamente en APIs modernas y SPAs, lo que hace estos ataques particularmente impactantes.
Cómo Funciona Ataque JWT (JSON Web Token)
Los ataques JWT apuntan al ciclo de vida del token: creación, transmisión, verificación y almacenamiento. La estructura del token (header.payload.signature) contiene claims sensibles pero frecuentemente se valida de forma inadecuada. Los atacantes manipulan tokens para cambiar roles de usuario, extender la expiración, falsificar firmas o evadir la verificación por completo. A diferencia de las cookies de sesión gestionadas del lado del servidor, los JWTs son sin estado — una vez emitidos, el servidor debe validarlos sin consulta a la base de datos, aumentando el riesgo de errores de implementación.
Analizar la implementación JWT
Identificar cómo se generan, transmiten y validan los tokens. Verificar si hay secretos débiles (palabras de diccionario, claves cortas), algoritmos inseguros (none, HS256 cuando se espera RS256), validaciones de claims faltantes (exp, iat, nbf), y reutilización de tokens entre diferentes contextos de seguridad.
Explotar la verificación débil
Si el servidor no verifica la firma adecuadamente, los atacantes pueden falsificar tokens. Se prueba eliminando la firma por completo (configurar 'alg': 'none') o firmando con secretos débiles o robados. Algunas bibliotecas aceptan tokens sin verificación de firma si el algoritmo se establece explícitamente como 'none'.
Manipular los claims del token
Si los tokens están firmados con un secreto débil o conocido, se decodifican y modifican los claims para elevar privilegios. Objetivos comunes: 'role' (admin), 'sub' (ID de usuario), 'exp' (expiración), o claims personalizados que controlan el acceso. Se firma nuevamente con el secreto comprometido y se envía a la aplicación.
Explotar la confusión de algoritmos
Algunas bibliotecas JWT permiten al atacante especificar el algoritmo de firma. Los atacantes cambian 'alg' de RS256 (clave pública) a HS256 (simétrico), engañando al servidor para que use la clave pública como clave de firma simétrica. Esto permite la falsificación de tokens sin la clave privada.
Ejemplos Reales
Vulnerabilidad crítica en bibliotecas JWT populares
Investigadores de seguridad descubrieron vulnerabilidades de confusión de algoritmos en múltiples bibliotecas JWT en diferentes lenguajes. La vulnerabilidad permitía a los atacantes evadir la verificación de firmas cambiando la cabecera de algoritmo de RS256 a HS256. Esto afectó a miles de aplicaciones, incluyendo sistemas empresariales y plataformas financieras que usaban versiones vulnerables de las bibliotecas.
Escalación de privilegios en plataforma SaaS mediante secreto JWT débil
Una plataforma SaaS usó un secreto JWT débil por defecto para desarrollo que fue accidentalmente desplegado en producción. Los atacantes descubrieron el secreto a través de variables de entorno expuestas, generaron tokens de administrador y obtuvieron acceso a todos los datos de clientes. La brecha expuso más de 50,000 registros de usuarios y resultó en una multa de $2.3 millones bajo GDPR.
Evasión del algoritmo none de JWT en arquitectura de microservicios
La arquitectura de microservicios de una empresa usaba JWT para autenticación entre servicios. Debido a una mala configuración, el servicio de verificación aceptaba tokens con 'alg': 'none', permitiendo a los atacantes evadir la autenticación por completo. Los atacantes accedieron a APIs internas, exfiltraron datos de clientes e interrumpieron el servicio durante 4 horas antes de la detección.
Impacto y Evaluación de Riesgo
Los ataques JWT permiten la toma de control completa de cuentas, la escalación de privilegios a acceso administrativo y el acceso no autorizado a APIs protegidas. En arquitecturas sin estado, los tokens comprometidos son difíciles de revocar rápidamente. Los atacantes pueden acceder a múltiples sistemas si los tokens se reutilizan entre servicios. El impacto incluye brechas de datos, fraude financiero, interrupción del servicio y violaciones de cumplimiento (GDPR, HIPAA, PCI DSS). Los sistemas con estado con gestión de sesiones pueden invalidar sesiones instantáneamente; los sistemas basados en JWT requieren listas de bloqueo de tokens o períodos de expiración cortos, aumentando la complejidad y el potencial de errores.
Cómo Detectar Ataque JWT (JSON Web Token)
Monitorear patrones sospechosos relacionados con JWT: tokens con 'alg': 'none', tokens inusualmente largos o cortos, tokens con firmas inválidas, tokens expirados siendo aceptados, o claims que no coinciden con los formatos esperados. Registrar todos los fallos de verificación JWT con metadatos completos del token (excluyendo secretos). Implementar detección de anomalías en los valores de claims (cambios de rol inesperados, fechas de expiración imposibles). Usar análisis estático para detectar bibliotecas JWT vulnerables o patrones de verificación inseguros en el código. Monitorear la reutilización de tokens entre diferentes direcciones IP o User Agents, indicando robo de tokens.
Cómo Prevenir Ataque JWT (JSON Web Token)
Usar secretos fuertes, criptográficamente aleatorios (mínimo 256 bits para HS256, 2048+ bits para RSA). Nunca usar el algoritmo 'none' en producción. Siempre verificar la firma antes de usar cualquier claim. Validar todos los claims críticos: expiración (exp), no antes (nbf), emitido en (iat), emisor (iss), audiencia (aud) y sujeto (sub). Usar versionado para esquemas de tokens para detectar cambios incompatibles. Implementar tiempos de vida cortos para tokens (15-30 minutos para tokens de acceso) con tokens de actualización almacenados de forma segura. Usar rotación de tokens para mitigar la reutilización. Implementar una lista de permitidos de algoritmos adecuada en las bibliotecas de verificación. Auditar regularmente las dependencias en busca de vulnerabilidades JWT conocidas. Considerar JWT con estado (agregando el claim jti y manteniendo una lista de bloqueo del lado del servidor) para operaciones críticas.
Ejemplos de Código
import jwt
# VULNERABLE: Weak secret and accepts any algorithm
SECRET = 'my-secret-key' # Dictionary word, weak!
def create_token(user_id, role):
return jwt.encode(
{'user_id': user_id, 'role': role},
SECRET,
algorithm='HS256'
)
def verify_token(token):
try:
return jwt.decode(token, SECRET, algorithms=['HS256', 'none'])
# ^ Accepts 'none' algorithm - vulnerable!
except jwt.InvalidTokenError:
return None
# Attacker can forge token by changing alg to 'none'
# and modifying role to 'admin'
import jwt
from datetime import datetime, timedelta
import os
# SECURE: Strong secret from environment
SECRET = os.getenv('JWT_SECRET')
if not SECRET or len(SECRET) < 32:
raise ValueError('JWT_SECRET must be at least 32 characters')
def create_token(user_id, role):
payload = {
'user_id': user_id,
'role': role,
'iat': datetime.utcnow(),
'exp': datetime.utcnow() + timedelta(minutes=15), # Short-lived
'iss': 'myapp.com', # Issuer validation
'aud': 'myapp-api' # Audience validation
}
return jwt.encode(payload, SECRET, algorithm='HS256')
def verify_token(token):
try:
payload = jwt.decode(
token,
SECRET,
algorithms=['HS256'], # Only accept HS256
issuer='myapp.com',
audience='myapp-api',
options={'require': ['exp', 'iat', 'iss', 'aud']}
)
# Additional business logic validation
if payload.get('role') not in ['user', 'admin']:
raise jwt.InvalidTokenError('Invalid role')
return payload
except jwt.ExpiredSignatureError:
raise ValueError('Token has expired')
except jwt.InvalidTokenError as e:
raise ValueError(f'Invalid token: {str(e)}')
const jwt = require('jsonwebtoken');
const crypto = require('crypto');
const JWT_SECRET = process.env.JWT_SECRET;
const TOKEN_VERSION = 'v1';
// Token blocklist (in production, use Redis)
const tokenBlocklist = new Set();
function createAccessToken(userId, role) {
return jwt.sign(
{
userId,
role,
version: TOKEN_VERSION,
type: 'access'
},
JWT_SECRET,
{
algorithm: 'HS256',
expiresIn: '15m',
issuer: 'myapp.com',
audience: 'myapp-api',
subject: userId.toString()
}
);
}
function createRefreshToken(userId) {
return jwt.sign(
{ userId, version: TOKEN_VERSION, type: 'refresh' },
JWT_SECRET,
{ algorithm: 'HS256', expiresIn: '7d' }
);
}
function verifyToken(token, expectedType = 'access') {
try {
const decoded = jwt.verify(token, JWT_SECRET, {
algorithms: ['HS256'],
issuer: 'myapp.com',
audience: 'myapp-api'
});
// Check if token is in blocklist
const jti = decoded.jti;
if (tokenBlocklist.has(jti)) {
throw new Error('Token has been revoked');
}
// Validate token type
if (decoded.type !== expectedType) {
throw new Error('Invalid token type');
}
// Check version for rotation
if (decoded.version !== TOKEN_VERSION) {
throw new Error('Token version outdated');
}
return decoded;
} catch (error) {
throw new Error(`Token verification failed: ${error.message}`);
}
}
// Revoke a token (e.g., on logout)
function revokeToken(token) {
const decoded = jwt.decode(token);
tokenBlocklist.add(decoded.jti);
}
Fortalece tus defensas contra Ataque JWT (JSON Web Token) con PowerWAF.
Seguridad integral para aplicaciones web con WAF, rate limiting y monitoreo de amenazas en tiempo real.
Los cupos del plan gratuito son limitados