Skip to main content
High

Ataque JWT (JSON Web Token)

CategoríaAutenticación y AccesoOWASPA07:2021 – Fallos de Identificación y AutenticaciónPrimera aparición2015Tiempo de lectura9 minVerificado2026-03-10
DEFINICIÓN

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.

1

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.

2

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'.

3

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.

4

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

2018

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.

2021

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.

2022

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

Vulnerable: Weak Secret and No Algorithm Check
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'
Secure: Proper JWT Implementation
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)}')
Secure: JWT Middleware with Rotation (Node.js)
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

Preguntas Frecuentes

La autenticación basada en sesiones almacena IDs de sesión en el servidor (base de datos, Redis) y requiere una consulta por cada solicitud. Los JWTs son tokens autónomos que incluyen todos los claims y se verifican criptográficamente sin almacenamiento del lado del servidor. Los JWTs son sin estado y escalan mejor, pero son más difíciles de revocar y más vulnerables a errores de implementación. Las sesiones proporcionan revocación más fácil pero requieren infraestructura de gestión de estado.
No, los secretos fuertes no previenen ataques de confusión de algoritmos, verificación de firma faltante ni validación débil de claims. Una defensa adecuada requiere múltiples capas: secretos fuertes, lista de permitidos de algoritmos, verificación de firma, validación de claims, expiración corta y uso de bibliotecas seguras. Cada capa aborda vectores de ataque diferentes.
Sí, 'alg': 'none' elimina la verificación de firmas, permitiendo que cualquiera falsifique tokens. El algoritmo 'none' está pensado solo para depuración y desarrollo, nunca para producción. Algunos casos de uso legítimos existen para claims no autenticados, pero estos deberían usar mecanismos separados, no JWT con 'none'. Siempre rechace tokens con 'alg': 'none' en producción.