OAuth to Account takeover

Tip

Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks

Información básica

OAuth ofrece varias versiones, con conocimientos fundamentales disponibles en OAuth 2.0 documentation. Esta discusión se centra principalmente en el ampliamente usado OAuth 2.0 authorization code grant type, proporcionando un marco de autorización que permite a una aplicación acceder o realizar acciones en la cuenta de un usuario en otra aplicación (el authorization server).

Considera un sitio hipotético https://example.com, diseñado para mostrar todas tus publicaciones en redes sociales, incluidas las privadas. Para lograr esto se emplea OAuth 2.0. https://example.com solicitará tu permiso para acceder a tus publicaciones en redes sociales. Como consecuencia, aparecerá una pantalla de consentimiento en https://socialmedia.com, que detalla las permisos solicitados y el desarrollador que realiza la solicitud. Tras tu autorización, https://example.com obtiene la capacidad de acceder a tus publicaciones en tu nombre.

Es esencial comprender los siguientes componentes dentro del framework OAuth 2.0:

  • resource owner: Tú, como usuario/entidad, autorizas el acceso a tu recurso, como las publicaciones de tu cuenta en redes sociales.
  • resource server: El servidor que gestiona las peticiones autenticadas después de que la aplicación haya obtenido un access token en nombre del resource owner, por ejemplo, https://socialmedia.com.
  • client application: La aplicación que solicita autorización del resource owner, como https://example.com.
  • authorization server: El servidor que emite access tokens a la client application tras la autenticación exitosa del resource owner y la obtención de la autorización, por ejemplo, https://socialmedia.com.
  • client_id: Un identificador público y único para la aplicación.
  • client_secret: Una clave confidencial, conocida únicamente por la aplicación y el authorization server, usada para generar access_tokens.
  • response_type: Un valor que especifica el tipo de token solicitado, como code.
  • scope: El nivel de acceso que la client application está solicitando al resource owner.
  • redirect_uri: La URL a la que se redirige al usuario después de la autorización. Normalmente debe coincidir con la URL de redirección pre-registrada.
  • state: Un parámetro para mantener datos durante la redirección del usuario hacia y desde el authorization server. Su unicidad es crítica para servir como mecanismo de protección CSRF.
  • grant_type: Un parámetro que indica el tipo de grant y el tipo de token que será devuelto.
  • code: El código de autorización del authorization server, usado junto con client_id y client_secret por la client application para obtener un access_token.
  • access_token: El token que la client application usa para peticiones a la API en nombre del resource owner.
  • refresh_token: Permite a la aplicación obtener un nuevo access_token sin volver a solicitar al usuario.

Flow

El flujo real de OAuth procede de la siguiente manera:

  1. Navegas a https://example.com y seleccionas el botón “Integrate with Social Media”.
  2. El sitio envía una petición a https://socialmedia.com solicitando tu autorización para que la aplicación de https://example.com acceda a tus publicaciones. La solicitud está estructurada así:
https://socialmedia.com/auth
?response_type=code
&client_id=example_clientId
&redirect_uri=https%3A%2F%2Fexample.com%2Fcallback
&scope=readPosts
&state=randomString123
  1. Se te presenta una página de consentimiento.
  2. Tras tu aprobación, Social Media envía una respuesta al redirect_uri con los parámetros code y state:
https://example.com?code=uniqueCode123&state=randomString123
  1. https://example.com utiliza este code, junto con su client_id y client_secret, para realizar una solicitud del lado del servidor y obtener un access_token en tu nombre, permitiendo el acceso a los permisos a los que consentiste:
POST /oauth/access_token
Host: socialmedia.com
...{"client_id": "example_clientId", "client_secret": "example_clientSecret", "code": "uniqueCode123", "grant_type": "authorization_code"}
  1. Finalmente, el proceso concluye cuando https://example.com emplea tu access_token para realizar una llamada API a Social Media para acceder

Vulnerabilidades

redirect_uri abierto

Per RFC 6749 §3.1.2, el authorization server debe redirigir el navegador solo a redirect URIs exactos y pre-registrados. Cualquier debilidad aquí permite a un atacante enviar a la víctima a través de una URL de autorización maliciosa para que el IdP entregue el code (y el state) de la víctima directamente a un endpoint del atacante, que luego puede canjearlo y cosechar tokens.

Flujo típico de ataque:

  1. Crear https://idp.example/auth?...&redirect_uri=https://attacker.tld/callback y enviarlo a la víctima.
  2. La víctima se autentica y aprueba los scopes.
  3. El IdP redirige a attacker.tld/callback?code=<victim-code>&state=... donde el atacante registra la petición y canjea inmediatamente el code.

Errores comunes de validación a probar:

  • No validation – se acepta cualquier URL absoluta, resultando en robo instantáneo del code.
  • Comprobaciones débiles por substring/regex en el host – bypass con parecidos como evilmatch.com, match.com.evil.com, match.com.mx, matchAmatch.com, evil.com#match.com, o match.com@evil.com.
  • Coincidencias homógrafas IDN – la validación se hace sobre la forma punycode (xn--), pero el navegador redirige al dominio Unicode controlado por el atacante.
  • Paths arbitrarios en un host permitido – apuntar el redirect_uri a /openredirect?next=https://attacker.tld o a cualquier endpoint de XSS/contenido de usuario filtra el code ya sea por redirecciones encadenadas, cabeceras Referer, o JavaScript inyectado.
  • Restricciones de directorio sin normalización – patrones como /oauth/* pueden ser eludidos con /oauth/../anything.
  • Subdominios wildcard – aceptar *.example.com significa que cualquier takeover (dangling DNS, S3 bucket, etc.) inmediatamente proporciona un callback válido.
  • Callbacks sin HTTPS – permitir URIs http:// da a atacantes en la red (Wi‑Fi, proxy corporativo) la oportunidad de capturar el code en tránsito.

Revisa también parámetros auxiliares de tipo redirect (client_uri, policy_uri, tos_uri, initiate_login_uri, etc.) y el OpenID discovery document (/.well-known/openid-configuration) para endpoints adicionales que puedan heredar las mismas fallas de validación.

XSS en la implementación de redirect

Como se menciona en este informe de bug bounty https://blog.dixitaditya.com/2021/11/19/account-takeover-chain.html, puede ser posible que la URL de redirect se refleje en la respuesta del servidor después de que el usuario se autentique, siendo vulnerable a XSS. Posible payload para probar:

https://app.victim.com/login?redirectUrl=https://app.victim.com/dashboard</script><h1>test</h1>

CSRF - Manejo incorrecto del parámetro state

El state parameter es el Authorization Code flow CSRF token: el cliente debe generar un cryptographically random value per browser instance, persistirlo en un lugar que solo ese navegador pueda leer (cookie, local storage, etc.), enviarlo en la authorization request y rechazar cualquier respuesta que no devuelva el mismo valor. Siempre que el valor sea estático, predecible, opcional o no esté ligado a la sesión del usuario, el atacante puede completar su propio OAuth flow, capturar la petición final ?code= (sin enviarla) y más tarde coaccionar al navegador de la víctima para que reejecute esa petición y así la cuenta de la víctima quede vinculada al perfil del atacante en el IdP.

El patrón de replay siempre es el mismo:

  1. El atacante se autentica contra el IdP con su cuenta e intercepta el último redirect que contiene code (y cualquier state).
  2. Descarta esa petición, guarda la URL y más tarde abusa de cualquier primitiva CSRF (enlace, iframe, formulario que se auto-envía) para forzar al navegador víctima a cargarla.
  3. Si el cliente no aplica state, la aplicación consume el resultado de autorización del atacante e inicia sesión al atacante en la cuenta de la víctima en la app.

Lista práctica de verificación para el manejo de state durante las pruebas:

  • Falta state por completo – si el parámetro nunca aparece, todo el login es vulnerable a CSRF.
  • state no requerido – elimínalo de la petición inicial; si el IdP aún emite codes que el cliente acepta, la defensa es opt-in.
  • state devuelto no validado – manipula el valor en la respuesta (Burp, MITM proxy). Aceptar valores que no coinciden significa que el token almacenado nunca se compara.
  • state predecible o puramente basado en datos – muchas apps meten rutas de redirección o blobs JSON en state sin mezclar entropía, permitiendo a atacantes adivinar valores válidos y reproducir flujos. Siempre anteponer/añadir entropía fuerte antes de codificar los datos.
  • Fijación de state – si la app permite a usuarios suministrar el valor state (p. ej., vía authorization URLs manipuladas) y lo reutiliza durante el flujo, un atacante puede fijar un valor conocido y reutilizarlo entre víctimas.

PKCE puede complementar a state (especialmente para public clients) vinculando el authorization code a un code verifier, pero los web clients aún deben rastrear state para prevenir bugs de CSRF entre usuarios / account-linking.

Pre Account Takeover

  1. Sin verificación de email al crear la cuenta: Los atacantes pueden crear preventivamente una cuenta usando el email de la víctima. Si la víctima luego usa un servicio de terceros para el login, la aplicación podría enlazar inadvertidamente esa cuenta de terceros con la cuenta pre-creada del atacante, provocando acceso no autorizado.
  2. Explotando verificación de email laxa en OAuth: Los atacantes pueden explotar servicios OAuth que no verifican emails registrándose y luego cambiando el email de la cuenta al de la víctima. Este método presenta un riesgo similar de acceso no autorizado a la cuenta, parecido al primer escenario pero mediante otro vector de ataque.

Disclosure of Secrets

El client_id es intencionalmente público, pero el client_secret nunca debe ser recuperable por usuarios finales. Los despliegues de Authorization Code que incrustan el secret en mobile APKs, desktop clients, or single-page apps entregan efectivamente esa credencial a cualquiera que pueda descargar el paquete. Siempre inspecciona public clients mediante:

  • Desempaquetar el APK/IPA, el instalador de escritorio o la app Electron y grepear por client_secret, blobs Base64 que decodifican a JSON, o endpoints OAuth hard-codeados.
  • Revisar archivos de configuración incluidos (plist, JSON, XML) o strings decompilados en busca de credenciales de cliente.

Una vez que el atacante extrae el secret, solo necesita robar cualquier authorization code de la víctima (vía un redirect_uri débil, logs, etc.) para golpear /token de forma independiente y acuñar access/refresh tokens sin involucrar la app legítima. Trata a los public/native clients como incapaces de mantener secretos —deben en su lugar apoyarse en PKCE (RFC 7636) para probar la posesión de un code_verifier por instancia en lugar de un secret estático. Durante las pruebas, confirma si PKCE es obligatorio y si el backend realmente rechaza intercambios de token que omiten ya sea el client_secret o un code_verifier válido.

Client Secret Bruteforce

Puedes intentar bruteforce the client_secret de un service provider con el identity provider para intentar robar cuentas.
La petición para BF puede verse similar a:

POST /token HTTP/1.1
content-type: application/x-www-form-urlencoded
host: 10.10.10.10:3000
content-length: 135
Connection: close

code=77515&redirect_uri=http%3A%2F%2F10.10.10.10%3A3000%2Fcallback&grant_type=authorization_code&client_id=public_client_id&client_secret=[bruteforce]

Referer Header leaking Code + State

Una vez que el cliente tiene el code and state, si se reflejan dentro del Referer header cuando navega a otra página, entonces es vulnerable.

Access Token Stored in Browser History

La garantía principal del Authorization Code grant es que access tokens nunca llegan al navegador del resource owner. Cuando las implementaciones leak tokens client-side, cualquier fallo menor (XSS, Referer leak, proxy logging) se convierte en un compromiso de cuenta instantáneo. Revisa siempre:

  • Tokens in URLs – si access_token aparece en la query/fragment, queda en el historial del navegador, server logs, analytics y en los Referer headers enviados a terceros.
  • Tokens transiting untrusted middleboxes – devolver tokens por HTTP o a través de proxies de depuración/corporativos permite a observadores de red capturarlos directamente.
  • Tokens stored in JavaScript state – React/Vue stores, variables globales o blobs JSON serializados exponen los tokens a cualquier script del origin (incluyendo XSS payloads o extensiones maliciosas).
  • Tokens persisted in Web StoragelocalStorage/sessionStorage retienen tokens mucho después del logout en dispositivos compartidos y son accesibles por scripts.

Cualquiera de estos hallazgos normalmente eleva bugs considerados “low” (como un CSP bypass o DOM XSS) a una toma completa de la API porque el atacante puede simplemente leer y volver a reproducir el leaked bearer token.

Everlasting Authorization Code

Los Authorization codes deben ser de corta duración, de un solo uso y resistentes al replay. Al evaluar un flujo, captura un code y:

  • Test the lifetime – RFC 6749 recomienda minutos, no horas. Intenta canjear el code después de 5–10 minutos; si todavía funciona, la ventana de exposición para cualquier leaked code es excesiva.
  • Test sequential reuse – envía el mismo code dos veces. Si la segunda petición devuelve otro token, los atacantes pueden clonar sesiones indefinidamente.
  • Test concurrent redemption/race conditions – lanza dos peticiones de token en paralelo (Burp intruder, turbo intruder). Algunos emisores débiles a veces conceden ambos.
  • Observe replay handling – un intento de reuse no solo debería fallar, sino también revocar cualquier token ya emitido a partir de ese code. De lo contrario, un replay detectado deja activo el primer token del atacante.

Combinar un code amigable con replay con cualquier redirect_uri o bug de logging permite acceso persistente a cuentas incluso después de que la víctima complete el login legítimo.

Authorization/Refresh Token not bound to client

Si puedes obtener el authorization code y usarlo con un cliente diferente, entonces puedes takeover otras cuentas.

Happy Paths, XSS, Iframes & Post Messages to leak code & state values

Check this post

AWS Cognito

En este bug bounty report: https://security.lauritz-holtmann.de/advisories/flickr-account-takeover/ puedes ver que el token que AWS Cognito devuelve al usuario podría tener suficientes permisos para sobrescribir los datos del usuario. Por lo tanto, si puedes change the user email for a different user email, podrías ser capaz de take over las cuentas de otros.

# Read info of the user
aws cognito-idp get-user --region us-east-1 --access-token eyJraWQiOiJPVj[...]

# Change email address
aws cognito-idp update-user-attributes --region us-east-1 --access-token eyJraWQ[...] --user-attributes Name=email,Value=imaginary@flickr.com
{
"CodeDeliveryDetailsList": [
{
"Destination": "i***@f***.com",
"DeliveryMedium": "EMAIL",
"AttributeName": "email"
}
]
}

Para más información detallada sobre cómo abusar de AWS Cognito consulta AWS Cognito - Unauthenticated Enum Access.

Abuso de tokens de otras Apps

Como se menciona en este writeup, los flujos OAuth que esperan recibir el token (y no un code) podrían ser vulnerables si no comprueban que el token pertenece a la app.

Esto se debe a que un atacante podría crear una application supporting OAuth and login with Facebook (por ejemplo) en su propia aplicación. Luego, una vez que una víctima inicia sesión con Facebook en la attackers application, el atacante podría obtener el OAuth token of the user given to his application, and use it to login in the victim OAuth application using the victims user token.

Caution

Por lo tanto, si el atacante consigue que el usuario acceda a su propia OAuth application, podrá tomar el control de la cuenta de la víctima en aplicaciones que esperan un token y no comprueban si el token fue concedido al app ID correspondiente.

Según este writeup, era posible hacer que una víctima abriera una página con un returnUrl apuntando al host del atacante. Esta información se almacenaría en una cookie (RU) y en un paso posterior el prompt preguntaría al usuario si desea dar acceso a ese host del atacante.

Para evadir este prompt, era posible abrir una pestaña que iniciara el Oauth flow que establecería esta cookie RU usando el returnUrl, cerrar la pestaña antes de que se muestre el prompt y abrir una nueva pestaña sin ese valor. Entonces, el prompt no informará sobre el host del atacante, pero la cookie quedaría configurada hacia él, por lo que el token será enviado al host del atacante en la redirección.

Bypass de interacción del prompt

Como se explica en este video, algunas implementaciones de OAuth permiten indicar el parámetro GET prompt como None (&prompt=none) para evitar que se pregunte a los usuarios confirmar el acceso en un prompt en la web si ya están autenticados en la plataforma.

response_mode

Como se explica en este video, podría ser posible indicar el parámetro response_mode para especificar dónde quieres que se entregue el code en la URL final:

  • response_mode=query -> El code se entrega dentro de un parámetro GET: ?code=2397rf3gu93f
  • response_mode=fragment -> El code se entrega dentro del fragmento de la URL #code=2397rf3gu93f
  • response_mode=form_post -> El code se entrega dentro de un form POST con un input llamado code y su value
  • response_mode=web_message -> El code se envía en un post message: window.opener.postMessage({"code": "asdasdasd...

Clickjacking en diálogos de consentimiento OAuth

Los diálogos de consentimiento/login OAuth son objetivos ideales para clickjacking: si pueden ser embebidos (framed), un atacante puede superponer gráficos personalizados, ocultar los botones reales y engañar a los usuarios para que aprueben scopes peligrosos o vinculen cuentas. Construye PoCs que:

  1. Carguen la URL de autorización del IdP dentro de un
  2. Usen posicionamiento absoluto/trucos de opacidad para alinear botones falsos con los controles ocultos Allow/Approve.
  3. Opcionalmente prellenar parámetros (scopes, redirect URI) para que la aprobación robada beneficie inmediatamente al atacante.

Durante las pruebas verifica que las páginas del IdP emitan X-Frame-Options: DENY/SAMEORIGIN o una Content-Security-Policy: frame-ancestors 'none' restrictiva. Si ninguna está presente, demuestra el riesgo con herramientas como NCC Group’s clickjacking PoC generator y registra lo sencillo que es para una víctima autorizar la app del atacante. Para ideas adicionales de payloads ver Clickjacking.

OAuth ROPC flow - bypass de 2FA

Según este post, este es un flujo OAuth que permite autenticarse vía username y password. Si durante este flujo simple se devuelve un token con acceso a todas las acciones que el usuario puede realizar, entonces es posible bypassear 2FA usando ese token.

ATO en página web que redirige basado en open redirect al referrer

Este blogpost explica cómo fue posible abusar de un open redirect hacia el valor del referrer para usar OAuth y lograr un ATO. El ataque fue:

  1. La víctima accede a la página web del atacante.
  2. La víctima abre el enlace malicioso y un opener inicia el Google OAuth flow con response_type=id_token,code&prompt=none como parámetros adicionales usando como referrer el sitio del atacante.
  3. En el opener, después de que el proveedor autoriza a la víctima, la envía de vuelta al valor de redirect_uri (sitio de la víctima) con un código 30X que aún mantiene el sitio del atacante en el referer.
  4. El sitio de la víctima dispara el open redirect basado en el referrer redirigiendo al usuario a la web del atacante; como el response_type fue id_token,code, el code se enviará de vuelta al atacante en el fragment de la URL permitiéndole takeover la cuenta del usuario vía Google en el sitio de la víctima.

Parámetros SSRFs

Revisa esta investigación para más detalles de esta técnica.

Dynamic Client Registration en OAuth sirve como un vector menos obvio pero crítico para vulnerabilidades de seguridad, específicamente para ataques de Server-Side Request Forgery (SSRF). Este endpoint permite a los servidores OAuth recibir detalles sobre aplicaciones cliente, incluyendo URLs sensibles que podrían ser explotadas.

Puntos clave:

  • Dynamic Client Registration suele mapearse a /register y acepta detalles como client_name, client_secret, redirect_uris, y URLs para logos o JSON Web Key Sets (JWKs) vía POST.
  • Esta funcionalidad se ajusta a las especificaciones en RFC7591 y OpenID Connect Registration 1.0, que incluyen parámetros potencialmente vulnerables a SSRF.
  • El proceso de registro puede exponer inadvertidamente servidores a SSRF de varias formas:
    • logo_uri: Una URL para el logo de la aplicación cliente que el servidor podría intentar obtener, desencadenando SSRF o leading a XSS si la URL se maneja incorrectamente.
    • jwks_uri: Una URL al documento JWK del cliente que, si está maliciosamente construida, puede hacer que el servidor realice solicitudes salientes a un servidor controlado por el atacante.
    • sector_identifier_uri: Referencia un array JSON de redirect_uris, que el servidor podría fetchear, creando una oportunidad SSRF.
    • request_uris: Lista URIs de request permitidas para el cliente, que puede explotarse si el servidor recupera estas URIs al inicio del proceso de autorización.

Estrategia de explotación:

  • Se puede desencadenar SSRF registrando un nuevo cliente con URLs maliciosas en parámetros como logo_uri, jwks_uri o sector_identifier_uri.
  • Aunque la explotación directa vía request_uris puede mitigarse con controles de whitelist, proporcionar un request_uri pre-registrado y controlado por el atacante puede facilitar SSRF durante la fase de autorización.

Abuso de OAuth/OIDC Discovery URL y ejecución de comandos OS

Investigación sobre CVE-2025-6514 (impactando clientes mcp-remote como Claude Desktop, Cursor o Windsurf) muestra cómo la discovery dinámica de OAuth se convierte en un primitivo RCE siempre que el cliente reenvíe metadata del IdP directamente al sistema operativo. El servidor MCP remoto devuelve un authorization_endpoint controlado por el atacante durante el intercambio de discovery (/.well-known/openid-configuration o cualquier RPC de metadata). mcp-remote ≤0.1.15 entonces llamaría al manejador de URLs del sistema (start, open, xdg-open, etc.) con cualquier cadena recibida, por lo que cualquier scheme/path soportado por el OS se ejecutaría localmente.

Flujo de ataque

  1. Apunta el agente de escritorio a un servidor MCP/OAuth hostil (npx mcp-remote https://evil). El agente recibe un 401 más metadata.
  2. El servidor responde con JSON tal como:
HTTP/1.1 200 OK
Content-Type: application/json

{
"authorization_endpoint": "file:/c:/windows/system32/calc.exe",
"token_endpoint": "https://evil/idp/token",
...
}
  1. El cliente lanza el handler del OS para la URI suministrada. Windows acepta payloads como file:/c:/windows/system32/calc.exe /c"powershell -enc ..."; macOS/Linux aceptan file:///Applications/Calculator.app/... o incluso esquemas personalizados como cmd://bash -lc '<payload>' si están registrados.
  2. Porque esto ocurre antes de cualquier interacción del usuario, merely configuring the client to talk to the attacker server yields code execution.

Cómo probar

  • Apunta a cualquier desktop/agent compatible con OAuth que realice discovery sobre HTTP(S) y abra los endpoints devueltos localmente (Electron apps, CLI helpers, thick clients).
  • Intercepta u hospeda la respuesta de discovery y reemplaza authorization_endpoint, device_authorization_endpoint, o campos similares con file://, cmd://, rutas UNC, u otros esquemas peligrosos.
  • Observa si el cliente valida el scheme/host. La falta de validación resulta en ejecución inmediata bajo el contexto del usuario y demuestra el problema.
  • Repite con diferentes esquemas para mapear toda la superficie de ataque (por ejemplo, ms-excel:, data:text/html,, custom protocol handlers) y demuestra el alcance multiplataforma.

Condiciones de carrera en proveedores OAuth

If the platform you are testing is an OAuth provider read this to test for possible Race Conditions.

Mutable Claims Attack

In OAuth, the sub field uniquely identifies a user, but its format varies by Authorization Server. To standardize user identification, some clients use emails or user handles. However, this is risky because:

  • Some Authorization Servers do not ensure that these properties (like email) remain immutable.
  • In certain implementations—such as “Login with Microsoft”—the client relies on the email field, which is user-controlled by the user in Entra ID and not verified.
  • An attacker can exploit this by creating their own Azure AD organization (e.g., doyensectestorg) and using it to perform a Microsoft login.
  • Even though the Object ID (stored in sub) is immutable and secure, the reliance on a mutable email field can enable an account takeover (for example, hijacking an account like victim@gmail.com).

Client Confusion Attack

In a Client Confusion Attack, an application using the OAuth Implicit Flow fails to verify that the final access token is specifically generated for its own Client ID. An attacker sets up a public website that uses Google’s OAuth Implicit Flow, tricking thousands of users into logging in and thereby harvesting access tokens intended for the attacker’s site. If these users also have accounts on another vulnerable website that does not validate the token’s Client ID, the attacker can reuse the harvested tokens to impersonate the victims and take over their accounts.

Scope Upgrade Attack

The Authorization Code Grant type involves secure server-to-server communication for transmitting user data. However, if the Authorization Server implicitly trusts a scope parameter in the Access Token Request (a parameter not defined in the RFC), a malicious application could upgrade the privileges of an authorization code by requesting a higher scope. After the Access Token is generated, the Resource Server must verify it: for JWT tokens, this involves checking the JWT signature and extracting data such as client_id and scope, while for random string tokens, the server must query the Authorization Server to retrieve the token’s details.

Redirect Scheme Hijacking

In mobile OAuth implementations, apps use custom URI schemes to receive redirects with Authorization Codes. However, because multiple apps can register the same scheme on a device, the assumption that only the legitimate client controls the redirect URI is violated. On Android, for instance, an Intent URI like com.example.app:// oauth is caught based on the scheme and optional filters defined in an app’s intent-filter. Since Android’s intent resolution can be broad—especially if only the scheme is specified—an attacker can register a malicious app with a carefully crafted intent filter to hijack the authorization code. This can enable an account takeover either through user interaction (when multiple apps are eligible to handle the intent) or via bypass techniques that exploit overly specific filters, as detailed by Ostorlab’s assessment flowchart.

References

Tip

Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks