スキル一覧に戻る
igbuend

oauth-security-anti-pattern

by igbuend

A repository of security related skills - like secure code review and pentesting - for Claude and other AI.

2🍴 1📅 2026年1月24日
GitHubで見るManusで実行

SKILL.md


name: "oauth-security-anti-pattern" description: "Security anti-pattern for OAuth implementation vulnerabilities (CWE-352, CWE-287). Use when generating or reviewing OAuth/OIDC authentication flows, state parameter handling, or token exchange. Detects missing CSRF protection and insecure redirect handling."

OAuth Security Anti-Pattern

Severity: High

Summary

OAuth 2.0/OIDC flows are complex and easily misconfigured. The critical mistake: failing to implement and validate the state parameter. This parameter defends against CSRF attacks during OAuth flows. Missing or predictable state allows attackers to trick victims into logging into the attacker's account, enabling account takeover.

The Anti-Pattern

The anti-pattern is initiating OAuth flows without state parameters, or using predictable values not validated on callback.

BAD Code Example

# VULNERABLE: The OAuth flow is initiated without a `state` parameter.
from flask import request, redirect

OAUTH_PROVIDER_URL = "https://provider.com/auth"
CLIENT_ID = "my-client-id"
CALLBACK_URL = "https://myapp.com/callback"

@app.route("/login/provider")
def oauth_login():
    # Redirects user to OAuth provider.
    # FLAW: No `state` parameter to prevent CSRF.
    auth_url = (f"{OAUTH_PROVIDER_URL}?client_id={CLIENT_ID}"
                f"&redirect_uri={CALLBACK_URL}&response_type=code")
    return redirect(auth_url)

@app.route("/callback")
def oauth_callback():
    # User redirected back from provider.
    # No way to verify callback corresponds to user-initiated flow.
    auth_code = request.args.get("code")
    # Exchanges code for tokens, logs user in.
    # Attacker can link victim's session to attacker's account.
    access_token = exchange_code_for_token(auth_code)
    log_user_in(access_token)
    return "Logged in successfully!"

Attack:

  1. Attacker initiates OAuth flow with own account
  2. Provider redirects to https://myapp.com/callback?code=ATTACKER_CODE
  3. Attacker intercepts and pauses request
  4. Attacker tricks victim into visiting malicious callback URL
  5. myapp.com associates victim's session with attacker's account

GOOD Code Example

# SECURE: A unique, unpredictable `state` is generated, stored in the session, and validated on callback.
from flask import request, redirect, session
import secrets

@app.route("/login/provider/secure")
def oauth_login_secure():
    # 1. Generate cryptographically random `state`.
    state = secrets.token_urlsafe(32)
    # 2. Store in user's session.
    session['oauth_state'] = state

    auth_url = (f"{OAUTH_PROVIDER_URL}?client_id={CLIENT_ID}"
                f"&redirect_uri={CALLBACK_URL}&response_type=code"
                f"&state={state}") # 3. Send state to provider.
    return redirect(auth_url)

@app.route("/callback/secure")
def oauth_callback_secure():
    # 4. Provider returns `state` in callback.
    received_state = request.args.get("state")
    auth_code = request.args.get("code")

    # 5. CRITICAL: Validate returned state matches session state.
    stored_state = session.pop('oauth_state', None)
    if stored_state is None or not secrets.compare_digest(stored_state, received_state):
        return "Invalid state parameter. CSRF attack detected.", 403

    # State valid, safe to proceed.
    access_token = exchange_code_for_token(auth_code)
    log_user_in(access_token)
    return "Logged in successfully!"

Detection

  • Trace the OAuth flow: Start at the point where your application redirects to the OAuth provider.
    • Is a state parameter being generated?
    • Is it cryptographically random and unpredictable?
  • Examine the callback endpoint:
    • Does it retrieve the state from the incoming request?
    • Does it compare it to a value stored in the user's session before the redirect?
    • Is the comparison done in constant time (hmac.compare_digest) to prevent timing attacks?
    • Is the state value single-use (i.e., deleted from the session after being checked)?

Prevention

  • Always use state parameter: Required in all OAuth/OIDC authorization requests.
  • Generate cryptographically random state: Minimum 32 characters. Never use predictable values (user ID, timestamp).
  • Bind to session: Store state in session cookie before redirect.
  • Strictly validate on callback: Compare request state with session value. Reject mismatches.
  • Make single-use: Remove from session after validation to prevent replay attacks.
  • Use PKCE for public clients: SPAs and mobile apps require PKCE (Proof Key for Code Exchange) in addition to state.

References

スコア

総合スコア

70/100

リポジトリの品質指標に基づく評価

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

+10
説明文

100文字以上の説明がある

+10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

0/5

レビュー

💬

レビュー機能は近日公開予定です