OIDC 実装で生まれうる脆弱性への対処
CSRF
state は推測困難な文字列とする
セッションごとに state を生成する
IdP から返された state とユーザーセッションに紐付いた state が一致しているかどうかの確認
つまり state は一連のセッションかどうかを判定するためのクレーム
クライアントからバックエンドに対して state クレームが渡されなかった場合はそのリクエストに対してエラーを返す
認可コードは短い有効期限に設定し、使用できるのは1回のみとする
リプレイ攻撃
クライアントは2回以上認可コードを使用してはいけない。もし2回以上使用された場合はリクエストを拒否しなければならず、この認可コードを基に発行されたこれまでのすべてのトークンを無効化すべき
nonce は推測困難な文字列とする
認証イベントごとに異なる nonce を使用する
id_token の検証完了後、nonce を無効化する
認可コード横取り攻撃
PKCE による対策を行う。PKCE はネイティブアプリへの認可コード横取り対策として導入された(注:実装メモ参照)
パラメータ
code_verifier
[A-Z] / [a-z] / [0-9] / - / . / _ / ~ からなる長さ43〜128文字のランダムな文字列
code_challenge
code_verifier に対して code_challenge_method の計算を施して算出された値
code_challenge_method
plain もしくは S256 が有効な値となる
基本的には S256 を用いるべき
トークンインジェクション
OAuth / OIDC におけるトークンインジェクションとは、攻撃者が攻撃者自身のアカウントに第三者のアクセストークンを適用することでアプリを通じて第三者のリソースにアクセスする攻撃のこと
OIDC では at_hash で対策する
OAuth では仕様上、防ぎようがない
Bearer Token はそもそもそういうもの
OAuth 認証用の scope が含まれている場合は注意が必要
トークンが漏れる経路
リファラーヘッダー
外部リンク先のサイト管理者はリファラーヘッダー内のクエリパラメータに含まれている認可コード等は参照可能となる
ブラウザログ
フラグメント・クエリパラメータどちらも漏洩する可能性がある
サーバーログ
SQL インジェクション
redirect_uri の検証をパターンマッチとしている
認可サーバーが redirect_uri のパターン登録を許可している場合に発生しうる脆弱性
Covert Redirect
コードインジェクション
OAuth
PKCE による対策
OIDC
nonce による対策
アプリ側はセッションと nonce の紐付けを管理
IdP 側は nonce と code の紐付けを管理
トークンレスポンスの時点で攻撃を検知可能
c_hash による対策
ID トークンに含まれる c_hash の値と code から算出される c_hash の値が一致しているか確認する
認証レスポンスの時点で攻撃を検知可能
nonce による対策はトークンレスポンスのあとに攻撃を検知できるが、c_hash は認証レスポンスの時点で検知できるため、高負荷が予想されるアプリケーションでは c_hash を使用して早いタイミングで検知するほうが望ましい
実装メモ
iss が IdP のものかどうか確認する
aud が受け取り者として自分の client_id が記載されていることを確認する
exp が有効期限を過ぎていないか確認する
署名を確認して id_token 自体が改ざんされていないことを確認する
redirect_uri はパターンマッチではなく完全一致とする
社内用であればおそらく自社ドメインのサブドメインをすべて許可するみたいなルールを設定するためそこまで注意深くしておく必要は無い気がしているが、何があっても良いようにちゃんと仕様に準拠しておくのがベターそう
PKCE はコンフィデンシャルクライアントにおいても MUST で利用するべき