1. Authorization Code Flow #flow
典型的な OAuth フロー(Web アプリ用):
① うつろい EC「LINE で連携」をクリック
↓
② ブラウザを LINE の認可画面へリダイレクト:
GET https://access.line.me/oauth2/v2.1/authorize
?client_id=utsuroi_app
&redirect_uri=https://shop.utsuroi.example.com/oauth/callback
&response_type=code
&state=abc123
↓
③ ユーザが LINE で「許可」を押す
↓
④ LINE が redirect_uri に認可コードを付けてリダイレクト:
https://shop.utsuroi.example.com/oauth/callback?code=auth_code_xyz&state=abc123
↓
⑤ うつろい EC のサーバが認可コードを LINE のトークンエンドポイントに POST し、
アクセストークンを取得 → ユーザのプロフィール取得 → ログイン完了
2. redirect_uri の検証ミス #redirect-uri
最も頻出する OAuth 脆弱性。
ID プロバイダ側で「許可された redirect_uri 一覧」と完全一致比較しないと、攻撃者の URL に認可コードを送らせることができる。
- prefix チェックの罠 — 許可リスト
https://shop.utsuroi.example.com/に対して、https://shop.utsuroi.example.com.evil.com/が prefix 一致で通る - サブドメインの過剰許可 —
*.utsuroi.example.comを許可すると、attacker.utsuroi.example.com(本物のドメイン上のサブドメインがどこかで奪取される、または XSS 経由)が悪用される - パス指定なし —
https://shop.utsuroi.example.comなら、/oauth/callback以外のオープンリダイレクト脆弱性のあるパスが指定できる - localhost 許可 — テスト用に localhost を許可していると、攻撃者がポートスキャン等に悪用
3. state パラメータ(CSRF 対策) #state
state は OAuth フローにおける CSRF 対策。攻撃者の認可コードを被害者ブラウザに「誰かに代わってログインさせる」攻撃を防ぐ。
- クライアントは認可リクエスト時にランダム
stateを生成、セッションに保存 - コールバック時に
stateがセッションのものと一致するかチェック - state を検証していない実装は CSRF 攻撃に脆弱
4. client_secret とパブリッククライアント #client-secret
client_secret はクライアント(うつろい EC)を ID プロバイダに対して認証するための値。サーバ側にだけ保管するべきもので、SPA・モバイルアプリのコードに含めてはいけない。
パブリッククライアント(SPA、ネイティブアプリ)では client_secret なしの PKCE フロー(Proof Key for Code Exchange)を使う。
5. 正しい防御 #defense
- redirect_uri は完全一致で検証 — prefix、ワイルドカード、サブドメイン許可は事故の元
- state パラメータを必ず使い、検証する — クライアント側のセッションに紐付けて
- PKCE をデフォルト採用 — パブリッククライアントだけでなく機密クライアントも使うのが現代のベストプラクティス
- 認可コードは1回限り、短命 — 使われた時点でサーバ側で無効化、有効期限は数十秒
- open redirect の排除 — redirect_uri に指定するエンドポイントは、それ自体に open redirect 脆弱性があってはいけない