「マイクロソフト系技術情報 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。
認可コード横取り攻撃 (authorization code interception attack) への対策
ネイティブアプリが、外部ブラウザを使用してOAuth 2.0認証要求を発行する場合、
「Implicit Flowではなく、Authorization Code Flowを使用し、
redirect_uriにPrivate-Use URI Schemeを使用してcodeを取得する。」
という方式があるが(下図を参照)、
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ | End Device (e.g., Smartphone) | | | | +-------------+ +----------+ | (6) Access Token +----------+ | |Legitimate | | Malicious|<--------------------| | | |OAuth 2.0 App| | App |-------------------->| | | +-------------+ +----------+ | (5) Authorization | | | | ^ ^ | Grant | | | | \ | | | | | | \ (4) | | | | | (1) | \ Authz| | | | | Authz| \ Code | | | Authz | | Request| \ | | | Server | | | \ | | | | | | \ | | | | | v \ | | | | | +----------------------------+ | | | | | | | (3) Authz Code | | | | Operating System/ |<--------------------| | | | Browser |-------------------->| | | | | | (2) Authz Request | | | +----------------------------+ | +----------+ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
このフローは、
+-------------------+ | Authz Server | +--------+ | +---------------+ | | |--(A)- Authorization Request ---->| | | | | + t(code_verifier), t_m | | Authorization | | | | | | Endpoint | | | |<-(B)---- Authorization Code -----| | | | | | +---------------+ | | Client | | | | | | +---------------+ | | |--(C)-- Access Token Request ---->| | | | | + code_verifier | | Token | | | | | | Endpoint | | | |<-(D)------ Access Token ---------| | | +--------+ | +---------------+ | +-------------------+
を使用して、code_verifierの妥当性を検証する。
# | パラメタ | 要否 | 説明 |
1 | code_challenge | 必須 | Code Verifier を元に計算された Code Challenge の値 |
2 | code_challenge_method | 任意 | Code Challenge の計算に用いるハッシュ関数。 "plain"と"S256"があり、デフォルトは "plain"。 |
# | パラメタ | 要否 | 説明 |
1 | code_verifier | 必須 | 動的に作成された暗号的にランダムな43-128文字のbase64url文字列 |
サーバー・ステートレスで"code"から"code_challenge"および"code_challenge_method"を
取り出す場合の処理は、当該サーバだけが可能になるように実装する必要がある。
code_challengeの生成にソルト(やストレッチ)が不要な理由。
このため、code_challengeの生成にソルト(やストレッチ)は不要。
OAuth PKCE、client_secretは不要と言うが、
OAuth PKCEでは、client_secretは不要で、client_idのみ、
client_secret_basic ではなく、client_secret_post っぽくポスト送付する模様。
① Resource Owner(ユーザ)がスマホ上のClient(スマホネイティブ・アプリ)をクリックする。
② Client(スマホネイティブ・アプリ)が起動する。
③ Client(スマホネイティブ・アプリ)のログイン ボタン or リンクをクリックする。
④ 外部ブラウザが起動して、Client(バックエンドWebアプリ)へWebアクセスする。
☆ CSRF対策、カスタムURLスキーム上書き攻撃対策として、
Client(スマホネイティブ・アプリ)は、固定でないstateに加えcode_verifierパラメタ付加しておく。
※ stateとcode_verifierパラメタは後で使用するので、Client(スマホネイティブ・アプリ)のローカル領域に保存しておく。
[ここからOAuth2のAuthoriaztion Codeフローでの認証]
⑤ Client(バックエンドWebアプリ)はClient(スマホネイティブ・アプリ)の要求を受けて
Authorization Serverへリダイレクト(OAuth2のAuthoriaztion Codeを開始)する。
☆ CSRF対策として、Client(バックエンドWebアプリ)は、
Client(スマホネイティブ・アプリ)から渡されたstateパラメタを付加する。
⑥ Authorization Serverがログイン画面を表示する。
⑦ Resource Owner(ユーザ)がクレデンシャル(ID, PWD)を入力する。
⑧ Authorization ServerはAuthoriaztion Code(code)を発行し
Client(バックエンドWebアプリ)のRedirectエンドポイントへリダイレクトする。
⑨ Client(バックエンドWebアプリ)は、先ず、stateパラメタを検証し、stateが問題なければ、
Authorization ServerのTokenエンドポイントへ AccessToken?リクエスト(codeを提示)する。
⑩ Authorization ServerからClient(バックエンドWebアプリ)へAccessToken?発行
⑪ Client(バックエンドWebアプリ)は、AccessToken?を使用してUserInfo?エンドポイントにリクエストし、
ユーザー情報が取得できたらユーザがログイン(認証/認可)されたこととする。
[ここまでOAuth2のAuthoriaztion Codeフローでの認証]
⑫ Client(バックエンドWebアプリ)は、Client(スマホネイティブ・アプリ)用の一時codeを生成してcode_verifierと紐つけて保持する。
⑬ 次に、カスタムURLスキームでClient(スマホネイティブ・アプリ)へリダイレクトし、これによって、一時codeとstateを渡す。
⑭ Client(スマホネイティブ・アプリ)は、一時codeとstateを受け取り、先ず、state検証する。
stateが問題なければ、一時codeと、④で指定したcode_verifierをClient(バックエンドWebアプリ)のTokenエンドポイントへポストする。
⑮ Client(バックエンドWebアプリ)のTokenエンドポイントは、
codeとcode_verifierを検証し、問題なければ認証tokenを発行する。
⑯ Client(スマホネイティブ・アプリ)は、認証tokenを取得する。
⑰ Client(スマホネイティブ・アプリ)は、 認証tokenを使用して
Client(バックエンドWebアプリ)のWebAPIへアクセスし、
正常系のリターンがあれば、ユーザがログイン(認証/認可)されたこととする。
Tags: :IT国際標準, :認証基盤, :クレームベース認証, :OAuth