← Volver al blog
Seguridad de autenticación 3 de abril de 2026 22 min de lectura

Lista de comprobación para pruebas de seguridad de OAuth: cómo encontrar vulnerabilidades de autenticación de alto impacto

Las vulnerabilidades de OAuth 2.0 encabezan sistemáticamente las listas de recompensas de severidad crítica en programas de bug bounty. Una sola toma de control de cuenta causada por una configuración incorrecta de OAuth puede derivar en el compromiso total de una organización, y estas vulnerabilidades aparecen en aplicaciones utilizadas por miles de millones de personas.

0K-00K
Recompensas por ATO mediante OAuth
Crítico
Clasificación del impacto
4.2B+
Usuarios afectados en todo el mundo
OWASP A07
Fallos de identidad y autenticación

Fundamentos de OAuth 2.0 para pruebas de seguridad

ℹ️ Los flujos de OAuth 2.0

Comprender qué flujo utiliza un objetivo determina qué ataques deben probarse. El flujo de código de autorización (con PKCE) es el más seguro y habitual. El ahora obsoleto flujo implícito presenta numerosas vulnerabilidades. Las credenciales de cliente (de máquina a máquina) tienen su propia superficie de ataque. Nunca debe usarse en producción: credenciales de contraseña del propietario del recurso.

Componentes clave de OAuth


Sección 1: interceptación del código de autorización

Prueba 1.1 — Redirección abierta en redirect_uri

Si el servidor de autorización valida redirect_uri con una precisión insuficiente, un atacante puede redirigir el código de autorización a un servidor bajo su control.

# Solicitud legítima
https://auth.example.com/oauth/authorize?
  client_id=app123&
  redirect_uri=https://app.com/callback&
  response_type=code&state=xyz

# Intentos de ataque
# 1. Recorrido de rutas
redirect_uri=https://app.com/callback/../../../evil.com/steal

# 2. Ruta adicional
redirect_uri=https://app.com.evil.com/callback

# 3. Evasión mediante fragmento
redirect_uri=https://app.com/callback%23@evil.com

# 4. Evasión mediante cadena de consulta
redirect_uri=https://app.com/callback?next=https://evil.com

Prueba 1.2 — Validación del parámetro state

⚠️ Un state ausente o débil equivale a CSRF en OAuth

El parámetro state evita ataques CSRF durante los flujos de OAuth. Si está ausente o es predecible, un atacante puede obligar a las víctimas a conectar sus cuentas con identidades controladas por él, lo que permite tomar el control de las cuentas.

# Compruebe si state:
# 1. Está presente en la solicitud de autorización
# 2. Se valida en la devolución de llamada
# 3. Es criptográficamente aleatorio (no secuencial ni predecible)
# 4. Es de un solo uso (los valores state reutilizados deben rechazarse)

# Prueba: reutilizar el mismo parámetro state
curl -s "https://app.com/oauth/callback?code=VALID_CODE&state=PREVIOUSLY_USED_STATE"
# Debe devolver: error (state ya utilizado)

Prueba 1.3 — Reutilización del código

# Los códigos de autorización deben ser de un solo uso
# Pruébelo reutilizando el código después del primer intercambio:

# Primer uso (legítimo)
POST /oauth/token
code=AUTH_CODE_123&grant_type=authorization_code&...

# Segundo uso (debe fallar)
POST /oauth/token
code=AUTH_CODE_123&grant_type=authorization_code&...
# Resultado esperado: {"error": "invalid_grant"}

Sección 2: pruebas de evasión de PKCE

Prueba 2.1 — Aplicación obligatoria de PKCE

PKCE evita los ataques de interceptación del código de autorización. Si un servidor compatible con PKCE no exige su uso, los clientes públicos son vulnerables.

# Iniciar el flujo CON PKCE (legítimo)
code_verifier = generate_random_string(64)
code_challenge = base64url(sha256(code_verifier))

GET /authorize?
  code_challenge=abc123&
  code_challenge_method=S256&...

# Ataque: intercambiar el código SIN proporcionar code_verifier
POST /token
grant_type=authorization_code&
code=INTERCEPTED_CODE&
redirect_uri=https://legitimate-app.com/callback
# Falta: code_verifier
# Si funciona -> PKCE no se aplica obligatoriamente -> Vulnerabilidad crítica

Prueba 2.2 — Degradación de code_challenge_method

# Intentar degradar de S256 a plain (menos seguro)
GET /authorize?
  code_challenge=ACTUAL_CODE_VERIFIER&
  code_challenge_method=plain&...
  
# Si se acepta: el servidor podría estar usando plain en lugar de S256
# Después, intercambiar con code_verifier = texto sin formato original
POST /token
code_verifier=ORIGINAL_PLAIN_TEXT&...

Sección 3: vulnerabilidades de los tokens

Prueba 3.1 — Filtración del token de acceso mediante Referer

⚠️ Tratamiento de tokens en fragmentos frente a consultas

En el flujo implícito (obsoleto, pero aún presente), los tokens de acceso incluidos en fragmentos de URL (#access_token=...) no se envían en las cabeceras Referer, pero los tokens incluidos en parámetros de consulta (?access_token=...) sí. Compruebe siempre cómo aparecen los tokens en las URL.

Prueba 3.2 — Escalada del alcance del token

# Solicitar un alcance mínimo
GET /authorize?scope=read:email&...

# Después de obtener el token de acceso, probar llamadas no autorizadas a la API
GET /api/user/delete
Authorization: Bearer ACCESS_TOKEN_WITH_READ_SCOPE
# Debe devolver 403, no 200

Prueba 3.3 — Vulnerabilidades en tokens de acceso JWT

# Si los tokens de acceso son JWT, pruebe:

# 1. Confusión de algoritmos (RS256 -> HS256)
header = {"alg": "HS256", "typ": "JWT"}
# Firmar usando la clave pública como secreto HMAC

# 2. Algoritmo none
header = {"alg": "none", "typ": "JWT"}
# Algunas bibliotecas aceptan tokens sin firmar

# 3. Inyección en kid (si se utiliza 'kid')
header = {"alg": "HS256", "kid": "' OR 1=1--"}
# Inyección SQL en el parámetro kid

# Herramientas:
# jwt_tool: python3 jwt_tool.py TOKEN -T (manipular)
# jwt-cracker: para secretos débiles

Prueba 3.4 — Evasión de la rotación del token de actualización

# Probar si los tokens de actualización antiguos se invalidan después de la rotación
POST /token
grant_type=refresh_token&refresh_token=OLD_REFRESH_TOKEN

# Si devuelve un token nuevo -> el token antiguo no se invalidó
# Un atacante que haya robado el token de actualización antiguo aún puede obtener nuevos tokens de acceso

Sección 4: escenarios de toma de control de cuentas

Prueba 4.1 — Vinculación de cuentas mediante OAuth sin verificación del correo electrónico

💡 Patrón de hallazgo de alto impacto

Si una víctima se registra con correo electrónico y contraseña (correo: victim@gmail.com) y un atacante puede vincular una cuenta de Google mediante OAuth con el mismo correo para tomar el control de la cuenta de la víctima, sin que Google verifique la propiedad, se trata de una toma de control de cuenta crítica. Esto es especialmente habitual en plataformas que permiten vincular varios proveedores de autenticación.

Prueba 4.2 — Toma de control previa de una cuenta

# Escenario de ataque:
# 1. El atacante crea una cuenta con victim@example.com (antes de que se registre la víctima)
# 2. El atacante vincula su proveedor de OAuth a este correo
# 3. Cuando la víctima se registra posteriormente mediante Google OAuth usando victim@example.com
# 4. La víctima obtiene acceso a la cuenta creada previamente por el atacante (o viceversa)

# Para probarlo:
# 1. Registrar una cuenta con el correo de la víctima (antes de que exista)
# 2. Conectar OAuth desde otro correo
# 3. Intentar acceder a la futura cuenta de la víctima

Prueba 4.3 — Fijación de tokens

# Algunas implementaciones permiten especificar access_token en la solicitud
# o no vinculan correctamente los tokens a las sesiones

# Prueba: forzar un valor de token conocido
GET /oauth/callback?access_token=KNOWN_VALUE

# Si la aplicación acepta y utiliza este token -> fijación de tokens

Prueba 4.4 — Confusión entre las declaraciones sub y email

# Si una aplicación vincula las cuentas al correo electrónico (y no a sub):
# Registrar un proveedor de OAuth malicioso con el correo de la víctima como declaración 'email'
# Algunos proveedores permiten establecer declaraciones de correo arbitrarias

# Probar creando un proveedor de OAuth personalizado con:
{
  "sub": "attacker-unique-id",
  "email": "victim@example.com",
  "email_verified": true
}

Sección 5: vulnerabilidades del servidor de autorización

Prueba 5.1 — Debilidad en la autenticación del cliente

# Los clientes confidenciales deben autenticarse mediante client_secret
# Probar si client_secret es opcional:
POST /token
grant_type=authorization_code&
code=CODE&
client_id=CONFIDENTIAL_CLIENT_ID&
# Falta: client_secret
# Si funciona -> la autenticación del cliente no se exige

Prueba 5.2 — Abuso del flujo de autorización de dispositivos

# El flujo de dispositivos (para dispositivos con entrada limitada) puede utilizarse para phishing
POST /device/code
client_id=LEGITIMATE_CLIENT

# Devuelve un user_code que la víctima introduce en verification_uri
# El atacante lo utiliza para ingeniería social:
# "Introduzca el código XXXX-XXXX en accounts.target.com/activate"

Lista completa de comprobación para pruebas de OAuth

Fase previa a la autorización

Pruebas de solicitudes de autorización

Pruebas del intercambio de tokens

Pruebas de seguridad de los tokens

Pruebas de vinculación de cuentas


Ejemplos reales de vulnerabilidades de OAuth

Tipo de vulnerabilidadPlataformaImpactoRecompensa
Evasión de redirect_uriFacebookToma de control de cuenta5,000
Ausencia del parámetro stateAirbnbCSRF → ATO$8,000
Reutilización del códigoMicrosoftAtaque de repetición5,000
Algoritmo none de JWTAuth0Evasión de la autenticación0,000
ATO por confusión de correo electrónicoSlackToma de control de cuenta0,000
PKCE no aplicado obligatoriamenteVariasInterceptación del código$5,000+

Herramientas de prueba

Automatice las pruebas de seguridad de OAuth

El escáner de KENSAI basado en IA prueba automáticamente sus implementaciones de OAuth para detectar interceptación del código de autorización, evasión de PKCE, vulnerabilidades de tokens y escenarios de toma de control de cuentas.

Iniciar análisis gratuito →

La seguridad no es opcional.

🗡️ El equipo de KENSAI

Artículos relacionados

La CVE de Smart Slider para WordPress afecta a 500K sitios web; TP-Link y Cisco IOS publican parches Interpol desmantela 45,000 direcciones IP maliciosas; Google corrige vulnerabilidades CVE-2026-28756: Cross-Site Scripting (XSS) en Zohocorp ManageEngine Exchange Reporter