Volver al blog
Vulnerabilidad14 min de lecturaActualizado el

OAuth account takeover en SaaS B2B: los 5 patrones de 2026

Los 5 patrones de account takeover vía OAuth en SaaS B2B: state confusion, redirect URI fuzz, code injection, PKCE bypass e implicit/hybrid flow.

Diego Melo, autor
Diego Melo

Investigador de seguridad y fundador de No Vuln

OAuth account takeover en SaaS B2B: los 5 patrones de 2026

El account takeover (ATO) vía OAuth es una de las clases de bug más lucrativas en los programas internacionales de bug bounty, y una de las menos cubiertas por el pentest tradicional en Brasil. El escáner no lo detecta. El checklist de OWASP no lo cubre bien. Y el vector es difícil porque depende de entender el protocolo, no solo de lanzar payloads en un campo de entrada.

Este artículo explica los 5 caminos de ATO vía OAuth que más aparecen en programas reales en 2025–2026, con ejemplos reales (anonimizados), y lo que el equipo defensivo tiene que hacer para bloquearlos.

Qué es OAuth, en una frase

OAuth 2.0 es un protocolo de autorización que permite que una aplicación (cliente) obtenga acceso a los recursos de un usuario en otra aplicación (proveedor) sin que el usuario tenga que compartir sus credenciales con la primera. Es como darle la llave de tu auto al valet del hotel: das un acceso limitado, sin entregar las llaves de tu casa.

OIDC (OpenID Connect) es una capa sobre OAuth 2.0 que agrega autenticación (saber quién es el usuario), no solo autorización.

Por qué OAuth es un vector frecuente de ATO

OAuth 2.0 tiene un diagrama con al menos 5 actores y 8 intercambios de mensajes. La especificación tiene más de 80 páginas. En la práctica:

  • El desarrollador lee la documentación por encima e implementa ~70% bien
  • El 30% incorrecto vive en los detalles que parecen opcionales
  • Y en esos detalles es donde vive el exploit

Vamos a los 5 caminos.

1. State confusion: el clásico que todavía funciona

El parámetro state sirve para vincular la solicitud inicial de autorización con la respuesta. Sin state, o con un state predecible, el atacante puede forjar la respuesta para la víctima.

Escenario típico:

  1. El atacante hace clic en “Conectar con Google” en su propia cuenta
  2. Captura la URL de callback generada por el proveedor (con el code)
  3. Le envía esa URL a la víctima como enlace de phishing
  4. La víctima hace clic con la sesión iniciada en la app: el callback se procesa contra la sesión de la víctima
  5. La cuenta del atacante queda vinculada al usuario de la víctima, o viceversa

Patrón recurrente en pentests: SaaS B2B donde el flujo de “conectar con Google” no valida bien el state: cualquier usuario puede ser forzado a vincular la cuenta del atacante mediante un enlace compartido en Slack o por email. Este vector aparece con frecuencia en programas públicos de bug bounty, con pagos de entre US$ 2.000 y US$ 15.000.

Cómo bloquearlo: state criptográficamente aleatorio (mínimo 128 bits), vinculado a la sesión y validado en el callback antes de procesar el code.

2. Redirect URI fuzz: el moderno y todavía subestimado

El proveedor OAuth valida el redirect_uri contra una lista preaprobada. Si la validación es débil, el atacante logra redirigir a su propio dominio con el code de la víctima.

Bypasses comunes:

  • Validación por prefijo: registraste https://app.com, el atacante usa https://app.com.evil.com
  • Validación por sufijo: registraste app.com/callback, el atacante usa https://evil.com/callback?x=app.com/callback
  • Validación que acepta parámetros de query: https://app.com/callback?next=https://evil.com (open redirect interno)
  • Path traversal: registraste https://app.com/oauth/callback, el atacante usa https://app.com/oauth/callback/../../external?url=evil.com
  • Subdomain takeover: registraste un subdominio con un CNAME que apunta a un SaaS abandonado

Cómo bloquearlo: validación por igualdad exacta (full string match). Sin wildcards, sin prefijo, sin sufijo. Lista de redirect_uri preregistrada y cerrada.

3. Code injection / code leakage

El code que devuelve el proveedor debe ser de un solo uso y de corta duración. Pero hay patrones en los que se filtra:

  • El code aparece en el header Referer si la página de callback carga imágenes externas
  • El code queda registrado en el servidor (proxy inverso, CDN, APM)
  • El code se guarda en localStorage y queda accesible para un XSS
  • El code se envía por GET a un endpoint con CORS abierto

Patrón recurrente en pentests: aplicaciones que registran los callbacks OAuth completos en herramientas de observabilidad (DataDog, Splunk, Sentry, New Relic): cualquier ingeniero con acceso a esos logs puede recolectar códigos de autorización de los usuarios y, sin PKCE obligatorio, canjearlos por access tokens válidos. Es un hallazgo clásico en auditorías de fintechs y SaaS B2B en producción.

Cómo bloquearlo:

  • PKCE obligatorio (incluso para clientes confidenciales)
  • Code con TTL corto (5 minutos como máximo, 30 segundos lo ideal)
  • Sanitización de logs (filtrar el campo code)
  • Header Referrer-Policy: no-referrer en la página de callback

4. PKCE bypass

PKCE (Proof Key for Code Exchange) se introdujo para proteger a los clientes públicos (apps móviles, SPA) de la interceptación del code. En 2026 también es obligatorio para los clientes confidenciales, en teoría.

Bypasses comunes:

  • El servidor acepta la solicitud sin code_verifier (PKCE opcional)
  • El servidor acepta code_challenge_method=plain (PKCE inútil)
  • El servidor acepta un code_verifier cuyo hash no coincide (validación ausente)
  • El servidor permite reutilizar el code_challenge entre solicitudes

Cómo bloquearlo: rechazar explícitamente las 4 condiciones anteriores. PKCE con S256, obligatorio y validado.

5. Implicit / hybrid flow que sigue existiendo en producción

OAuth 2.1 (todavía en borrador; se convertirá en RFC) declaró obsoletos el implicit flow y el hybrid flow con token en la URL. Son frágiles: el token aparece en la URL y queda en el historial del navegador, en logs y en el Referer. Pero en 2026 todavía existen en producción.

Escenario: app legacy con implicit flow. La víctima es redirigida a app.com/#access_token=abc123. El atacante puede leerlo:

  • Mediante un XSS inyectado en app.com
  • Mediante una extensión de navegador maliciosa instalada en el perfil de la víctima
  • Mediante un navigator.share abusado
  • Mediante subframe hijacking, si la página se puede embeber

Cómo bloquearlo: migrar a Authorization Code Flow + PKCE. No uses implicit. No uses hybrid con tokens en la URL. Si un cliente legacy necesita una migración gradual, aísla el implicit en un dominio separado y monitoréalo de forma agresiva.

Bonus: confused deputy cuando tú eres el cliente OAuth

Si tu aplicación consume OAuth de terceros (login con Google, Microsoft, Facebook), eres un cliente OAuth. Para protegerte:

  • Verifica el id_token (nonce, audience, issuer)
  • No confíes en un email no verificado que venga del proveedor
  • Vincula la cuenta del proveedor a la cuenta interna por sub (ID estable), no por email
  • Trata con cuidado el caso “el email ya existe”: si no, un atacante puede tomar una cuenta antigua solo cambiando el email en Google

Este último vector, la account confusion vía email no verificado, es hoy uno de los exploits de ATO más lucrativos. Un atacante con su propio Google Workspace configura un alias con el email del objetivo, se conecta a la app y queda vinculado a la cuenta de la víctima.

Cómo ataca todo esto un pentest serio

No Vuln usa el OAuth State Fuzzer (herramienta propietaria) para automatizar:

  • State guessing y replay
  • Redirect URI fuzz (más de 50 payloads de bypass)
  • PKCE downgrade attacks
  • Intentos de reutilización del code
  • JKU/X5U injection en ID tokens

Y, manualmente, el investigador valida cada camino con una PoC reproducible, alinea la severidad con el impacto en el negocio (ATO en una cuenta de admin enterprise = P0; en una cuenta de usuario común = P1 o P2, según los datos) y escribe una recomendación de corrección específica.

Conclusión

El ATO vía OAuth en 2026 es un exploit de detalle. No lo detecta el escáner. No lo detecta una revisión de checklist. Lo detecta un investigador que entiende el protocolo y tiene herramientas para hacer fuzzing de los más de 50 caminos de bypass.

Si tu aplicación tiene OAuth (y en 2026 casi todas lo tienen), un pentest superficial no te protege. Vale la pena buscar una consultora que mencione explícitamente los 5 vectores de este artículo antes de empezar.

Compartir

WhatsAppLinkedInX

Siguiente paso

¿Quieres aplicar esto a tu sistema?

No Vuln hace pentests en profundidad con la misma metodología descrita en este artículo. Solicita una propuesta: NDA bilateral en 24h y alcance definido en una llamada técnica.