マイクロソフト系技術情報 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。

目次

概要

認可コード横取り攻撃 (authorization code interception attack) への対策

  • (Authorization Codeグラント種別により発行された)
    認可コードをクライアントアプリケーションが受け取る際、
    悪意のあるアプリケーションがその認可コードを横取りする攻撃に対抗する仕様。

課題

ネイティブアプリが、外部ブラウザを使用して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 |          |
   | +----------------------------+ |                   +----------+
   +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
  • Private-Use URI Schemeの上書き攻撃によって、このcodeが傍受されることがある。
  • また、client_idや、client_secretも漏洩してしまう可能性がある。

対策

  • コード交換のための証明鍵(PKCE、 "pixy"と発音)を使用して脅威を軽減する。
  • プロビジョニングされたアプリケーションのバイナリ・ファイル中のclient_secretについては、
    機密性が考慮されていないため、client_secretを必要としない方式になっている。

仕様

仕様の概要

このフローは、

  • Client ≒ デバイス(UserAgent?)になる。
  • redirect_uriにPrivate-Use URI Schemeが使用される点を除いて、
    Authorization Code Flowと同じだが、下記リクエストにパラメタが追加される。
    • 認証リクエスト
    • Tokenリクエスト
                                                +-------------------+
                                                |   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 ---------|               | |
      +--------+                                | +---------------+ |
                                                +-------------------+

仕様の詳細

  • Clientは、認可リクエストを送信する前に、
    • 乱数 "code_verifier" を発生させ、
    • ハッシュ関数 "t" を用いた
    • ハッシュ値 "t(code_verifier)"を計算する。
  • Clientは、認可リクエストに以下のパラメタを含める。
    • code_challenge_method:ハッシュ関数 "t"
    • code_challenge:ハッシュ値 "t(code_verifier)"
  • 認可エンドポイントで、前述の認可リクエストを受信した際、これらを保存しておく。
  • Clientは、Tokenリクエストに、先程生成した code_verifierパラメタを含める。
  • Tokenエンドポイントでcode_verifierを含むTokenリクエストを受信した場合、保存されている
    • code_challenge_method:ハッシュ関数 "t"
    • code_challenge:ハッシュ値 "t(code_verifier)"

を使用して、code_verifierの妥当性を検証する。

  • なお、このフローでは、client_secretは不要とする。

各エンドポイントで受け取るパラメタ

  • 認可エンドポイント
    #パラメタ要否説明
    1code_challenge必須Code Verifier を元に計算された Code Challenge の値
    2code_challenge_method任意Code Challenge の計算に用いるハッシュ関数
    "plain"と"S256"があり、デフォルトは "plain"。
  • Tokenエンドポイント
    #パラメタ要否説明
    1code_verifier必須動的に作成された暗号的にランダムな43-128文字のbase64url文字列

ハッシュ関数

  • plain:
    • 恒等関数(引数と同じ戻り値を返すの意)
    • code_verifierをそのまま使用する(ClientでS256がサポートできない場合)。
  • S256:
    • BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))
    • SHA-256 でハッシュ化した値を base64url に変換したもの。

codeとの関連

  • サーバー・ステートレス
    通常、"code_challenge"および"code_challenge_method"の
    値は暗号化された形式で"code"自体に格納される。
  • サーバー・ステートフル
    codeに関連付けられたAuthorization Serverに格納することもできるが、
    "code_challenge"と"code"を関連付ける方法は、仕様の対象外。

セキュリティに関する考慮事項

code_verifier

  • code_verifierには充分なエントロピーが必要(256ビット以上)。
  • 生成には、適切なRNG(RNGCryptoServiceProvider?など)の使用が推奨される。

盗聴者からの保護

  • 通常、"S256"を使用する。
    PKCEをサポートするサーバーは"S256"をサポートする必要がある。
    • "plain"では、"code_challenge" = "code_verifier"となり盗聴が可能。
    • 従って、通常、"plain"ではなく、"S256"を使用する必要がある。
  • "plain"を使用する場合、

    サーバー・ステートレスで"code"から"code_challenge"および"code_challenge_method"を
    取り出す場合の処理は、当該サーバだけが可能になるように実装する必要がある。

code_challenge

code_challengeの生成にソルト(やストレッチ)が不要な理由。

  • ソルトによって、辞書空間が大幅に拡張される。
  • しかし、
    • code_verifierはpasswordと異なり、エントロピーが高い。
    • GPUの進化によってソルトの価値が減ってきている。

このため、code_challengeの生成にソルト(やストレッチ)は不要。

補足

client_secret不要?問題

概要

OAuth PKCEのアクセストークン・リクエストでは、client_secretは不要で、client_idのみでOK。

  • なので、client_secret_basic ではなく、client_secret_post っぽくポスト送付したりする。
  • Auth0では、client_secret_post でもなく、client_secret_query 的だったらしい。

参考

オレオレPKCE

概要

  • OAuth PKCEをサポートしていない Idp/Sts でClient側に実装を足して、
    PKCEッポくする処理シーケンス(本来は、リプレース予算の獲得するのが望ましい)。
  • よりセキュアに、OAuth PKCEっぽく実装する場合、
    code_verifierをそのまま使用するのではなく、以下のcode_challengeとして送信する。
    なお、アルゴリズム(code_challenge_method)は、今の所、"plain"と"S256"のみ。
    • code_challenge_method:ハッシュ関数 "t"
    • code_challenge:ハッシュ値 "t(code_verifier)"

フロー

① 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へアクセスし、
 正常系のリターンがあれば、ユーザがログイン(認証/認可)されたこととする。

スマホ向けPKCE

Authorization Code Grant Flow with PKCE

SPAでPKCEする場合のプロファイル。

参考

仕様

関連

OAuth PKCE利用時の構成図

OAuth 2.0 for Native Apps

OAuth 2.0 for Browser-Based Apps


Tags: :IT国際標準, :認証基盤, :クレームベース認証, :OAuth


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2021-04-21 (水) 16:28:54 (1093d)