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

目次

概要

  • このページは、ドラフト 15 を参考にして作成。
  • F-API2でのユースケースは限定的で分かり易いが、
    こちらのフルスペックは若干意味不明(私が理解できていないダケ)。

弱点

以下の弱点のために、

  • 通信の送信元が認証されていない。
  • TLS末端は保護されないため、パラメタ汚染、通信監視が可能。
    • TLSセッションは、UserAgent?で終了する。
    • TLSセッションは、ロードバランサなど(ミドルボックス)で時期尚早に終了することがある。

攻撃

以下の攻撃が可能。

  • Redirect URI書き換え攻撃
  • ミックスアタック攻撃[FETT]

対策

対策として、認可リクエストのパラメタ群をJWTで送信する
(認証要求に署名し、オプションで暗号化できる。)
OAuth 2.0 拡張OpenID Connectによって追加された。

効果

このアプリケーション層セキュリティの使用により、

  • 許可要求の機密性、完全性が達成され、
  • これらの問題が緩和される。

サード・パーティー

本仕様(コンテキスト)中で、「サード・パーティー」という用語は、以下に関連する。

Requestオブジェクト

内容

JWT化された認可リクエストのパラメタ群をRequestオブジェクトと呼ぶ。

生成方法

  • Requestオブジェクト(JWT)は、
    • JWSで署名し、
    • 必要に応じてJWEで暗号化する。
  • 署名と暗号化が必要な場合、
    • 署名の後、暗号化を行う(逆はダメ)。
    • 詳しくは[RFC7519]の11.2節を参照

効果

  • 合意した以上のアクセス権を要求できないようにすることで、プライバシーを保護する。
  • この場合、認可プロンプトをスキップすることが望ましい場合もある。
  • 以下のような少数例にも適合する。
    • 送信される要求のサイズを小さくすることが望ましい場合(秘密鍵?)。
    • Clientが暗号を行いたくないとき(JWSで署名し、TLSを使用する)。

クレームセット

Requestオブジェクト(JWT)のペイロードをbase64urlデコードした文字列。
認可Requestの全てのパラメタがRequestオブジェクトに同梱されている。

  • ヘッダ(共通)
    {
      "alg": "RS256",
      "kid": "k2bdc"
    }
  • ペイロード
    ※ nonceやmax_ageなどの拡張変数が含まれる。
  • 通常
    {
     "iss": "s6BhdRkqt3",
     "aud": "https://server.example.com",
     "response_type": "code id_token",
     "client_id": "s6BhdRkqt3",
     "redirect_uri": "https://client.example.org/cb",
     "scope": "openid",
     "state": "af0ifjsldkj",
     "nonce": "n-0S6_WzA2Mj",
     "max_age": 86400
    }
  • claimsリクエスト・パラメタを含む。
    {
      "iss": "s6BhdRkqt3",
      "aud": "https://server.example.com",
      "response_type": "code id_token",
      "client_id": "s6BhdRkqt3",
      "redirect_uri": "https://client.example.org/cb",
      "scope": "openid",
      "state": "af0ifjsldkj",
      "nonce": "n-0S6_WzA2Mj",
      "max_age": 86400,
      "claims": {
        "userinfo": {
          "given_name": {
            "essential": true
          },
          "nickname": null,
          "email": {
            "essential": true
          },
          "email_verified": {
            "essential": true
          },
          "picture": null
        },
        "id_token": {
          "gender": null,
          "birthdate": {
            "essential": true
          },
          "acr": {
            "values": [
              "urn:mace:incommon:iap:silver"
            ]
          }
        }
      }
    }

公開鍵

署名を検証する場合、JWK形式で表されるRSA公開鍵を使用する。
jwks_uriにJWK Setを公開する。

{
    "kty":"RSA",
    "kid":"k2bdc",
    "n":"y9Lqv4fCp6Ei-u2-ZCKq83YvbFEk6JMs_pSj76eMkddWRuWX2aBKGHAtKlE5P
        7_vn__PCKZWePt3vGkB6ePgzAFu08NmKemwE5bQI0e6kIChtt_6KzT5OaaXDF
        I6qCLJmk51Cc4VYFaxgqevMncYrzaW_50mZ1yGSFIQzLYP8bijAHGVjdEFgZa
        ZEN9lsn_GdWLaJpHrB3ROlS50E45wxrlg9xMncVb8qDPuXZarvghLL0HzOuYR
        adBJVoWZowDNTpKpk2RklZ7QaBO7XDv3uR7s_sf2g-bAjSYxYUGsqkNA9b3xV
        W53am_UZZ3tZbFTIh557JICWKHlWj5uzeJXaw",
    "e":"AQAB"
}

渡し方

Requestオブジェクトの渡し方にはrequestとrequest_uriの2つのパラメタを使用する方法がある。

  • requestとrequest_uriパラメタを、OAuth 2.0 の追加の認証要求パラメタとして導入。
  • パラメタは「application/x-www-form-urlencoded = QueryString?」として渡す。

requestパラメタ

Requestオブジェクトの値を直接渡す。

  • 認可エンドポイント
    https://server.example.com/authorize?request=eyJhbG..AlMGzw

request_uriパラメタ

  • 認可エンドポイント
    • Requestオブジェクトの場所をuriで伝える。
    • uriは、512 ASCII文字を超えてはならない。
      https://server.example.com/authorize?
        response_type=code%20id_token
        &client_id=s6BhdRkqt3
        &request_uri=https%3A%2F%2Ftfp.example.org%2Frequest.jwt
        %23GkurKxf5T0Y-mnPFCHqWOMiZi4VS138cQO_V7PZHAdM
        &state=af0ifjsldkj

※ この場合、response_type, client_id, state値の同梱が必要。
(下位互換などのため、)QueryString?に同じパラメタが指定できるダケ。

  • request_uriエンドポイント 通常は、ローカルの検索ではなく、HTTPのRequestを行う。
  • Request
    GET /request.jwt HTTP/1.1
    Host: tfp.example.org
  • Response
    HTTP/1.1 200 OK
        Date: Thu, 16 Feb 2017 23:52:39 GMT
        Server: Apache/2.2.22 (tfp.example.org)
        Content-type: application/jwt
        Content-Length: 1250
        Last-Modified: Wed, 15 Feb 2017 23:52:32 GMT
    
        ey・・・(JWT)・・・
  • アクセス制御対策
    • 第三者に公開しても良い。
    • Authorization Serverだけ公開するパラメタを含む場合、
      以下のように、存続期間に適切なエントロピーを持たせる。
      https://tfp.example.org/request.jwt#GkurKxf5T0Y-mnPFCHqWOMiZi4VS138cQO_V7PZHAdM

実装

下記手順で取得したRequestオブジェクトを署名検証(若しくは復号)する。

サード・パーティー

この章に書かれている「jwks_uriにJWK Setを公開」する実装例は、

  • サード・パーティーに依る「Assertion Created by Third Party」実装の場合か?
  • Clientに依る場合、「Self-Issued Assertion」実装で良い気がする。

復号化

Requestオブジェクトが暗号化されている場合、
下記手順で取得したRequestオブジェクトを復号化する。

復号化の処理

  • Requestオブジェクトの復号用の鍵を取得。
    クライアント・メタデータの登録・有無によってシーケンスが異なる。
  • 登録されている場合、
    JWK Setをjwks クライアントメタデータ値から取得。
  • 登録されていない場合、
    jwks_uriからクライアント・メタデータ(JWK Set)を取得。
  • Requestオブジェクトを復号化して、
    • 認可エンドポイントへのパラメタ
    • 若しくは、Requestオブジェクト(署名)

を取り出す。

復号化の失敗

復号化に失敗した場合、Authorization Serverは
「invalid_request_object」エラーを返す。

署名検証

下記手順で取得したRequestオブジェクトを署名検証する。

署名検証の処理

  • Requestオブジェクトの署名・検証用の鍵を取得。
    クライアント・メタデータの登録・有無によってシーケンスが異なる。
  • 登録されている場合、
    JWK Setをjwks クライアントメタデータ値から取得。
  • 登録されていない場合、
    jwks_uriからクライアント・メタデータ(JWK Set)を取得。
  • Requestオブジェクトから認可エンドポイントへのパラメタを取り出す。

署名検証の失敗

署名検証に失敗した場合、Authorization Serverは「invalid_request_object」エラーを返す。

パラメタ検証

Authorization Serverは、

  • (下位互換などのため、)QueryString?に同じパラメタが指定することもできる。
    しかし、パラメタ検証には、Requestオブジェクト内のパラメタのみを使用しなければならない。
  • 次にOAuth 2.0 [RFC6749]で指定された要求を検証する。

追加エラー値

requestパラメタ

  • request_not_supported
    Authorization Serverは、requestパラメタの使用をサポートしない。
  • invalid_request_object
    requestパラメタに無効なRequestオブジェクトが含まれている。

request_uriパラメタ

  • request_uri_not_supported
    Authorization Serverは、request_uriパラメタの使用をサポートしない。
  • invalid_request_uri
    request_uriパラメタに対する要求が、エラーか、無効なRequestオブジェクトを返す。

TLS要件

TLSをサポートしなければならない。

  • 秘密性と完全性の保護を提供し、情報の漏えいや改ざんから保護する。
  • man-in-the-middle攻撃を防ぐため、DNS-ID識別子を使用して、サーバ証明書を検証。

サーバ証明書要件

  • サーバ証明書のDNS名にワイルドカード文字「*」を含めることができる
  • DNS-ID識別子タイプ(つまり、subjectAltName?拡張子のdNSName ID)のサポートが必須
    • サーバ証明書を発行する認証機関はDNS-ID識別子タイプをサポート
    • DNS-ID識別子タイプはサーバ証明書に存在しなければならない

その他

  • クライアントはCN-ID識別子を(認証に)使用してはならない。
  • SRV-IDとURI-IDは、比較のために使用してはならない。

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

ソース認証

認可リクエストの送信元は常に検証されなければならない。

Requestオブジェクトの暗号処理

  • Requestオブジェクトの署名検証を行う。
  • Requestオブジェクトの復号用の秘密鍵が正しいか。

request_uriとサーバ証明書

request_uriのサーバ証明書のIDを帯域外で知っている必要がある
(ただし、これは、一般的に信頼された方法ではない(ので後述が推奨?))。

request_uriとclient_idのバインド

Authorization Serverは、

  • 受け入れたRequestオブジェクト中の、
    request_uriとclient_idをバインドするクライアント認証が必要。
  • このため、POSTされたRequestオブジェクトと引き換えに、
    request_uriを提供するエンドポイントを提供できる。
  • 以下を参照すると、恐らく、)ココのエンドポイントで何らかのクライアント認証を行う。
  • 返した、request_uriを使用すると、client_idを含むRequestオブジェクトを取得できる。
  • この場合の、request_uriの要件は、
    • 有効期間は短く、好ましくはワンタイムにする必要がある。
    • また、エントロピーは十分に大きくなければならない。
  • これらは、保護されるリソースの価値に依存するが、
    一般的なガイダンスは、以下の通り。
    • 有効時間の1分未満。
    • 128bit以上の暗号ランダム値を含める。

FAPI Part 2に実例がある。

Trust Framework Provider

上記エンドポイントがサード・パーティーのTrust Framework Providerによって提供されても良い。

  • 上記「request_uriとclient_idのバインド」と同じ要件が適用される。
  • Authorization Serverは、ClientがTrust Framework Providerを利用することを帯域外で知っている必要がある。

エンドポイント間のリンク

以下のエンドポイント間のリンクを張る拡張仕様が必要。
([FETT]で紹介されたクロスフェーズ攻撃を防止する)

  1. 認可エンドポイント( "authorization_endpoint")
  2. Redirect URI( "redirect_uri")
  3. Tokenエンドポイント( "token_endpoint")
  4. 保護されたリソース( "protected_resources")

request_uri関連のリスク

DDoS攻撃

  • 不正なクライアントが、不正な"request_uri"を指定する。
  • この場合、以下の攻撃が可能になる。
    • 非常に大きなコンテンツを返す。
    • 非常に遅く応答する。
    • 再帰的GETを引き起こす。

Request URI Rewrite

  • request_uriパラメタの値は署名されていないため、
    man-in-the-middle攻撃によって、改ざんされる可能性がある。
  • この場合、以下の攻撃が可能になる。
    • 書き換えられたURIが指し示す別のファイルを作成して、余分なscopeを要求できる。
    • 「request_uri」の値を犠牲者の値に設定することによって、DoS攻撃を開始する。

(再帰的GETもできそうだが・・・?)

対策

  1. request_uriパラメタの値が予期しない場所を指していないこと。
  2. 応答のコンテンツタイプが、"application/jwt"であること。
  3. request_uriの内容を取得するためのタイムアウトを実装すること。
  4. request_uriに対する再帰的GETを実行しないこと。

プライバシーに関する考慮事項

RFC6973

コレクションの制限

個人情報保護法のため、個人情報を含む場合、厳密にscopeを制限するべき。

  • Clientは、登録リクエスト行う。
  • Authorization Serverは、
    • request_uriがTrust Framework Providerのモノか検証する。
    • HTTP GET要求をrequest_uriに発行する。
    • TLS証明書のサーバIDがrequest_uriと一致するか確認する。
    • Clientを表す「client_id」を含むRequest Objectを取得する。
  • 認可画面は、
    • クライアントを指示しなければならず、
    • その要求が「コレクションの制限の原則に従うために、
      Trust Framework Providerによって審査されたこと。」を示すべき。

開示の制限

リクエストの開示

  • 問題
    • この仕様は、拡張パラメタを許可し、ここに機密情報が含まれる可能性がある。
    • 特にRefererとBrowser履歴を介して、Querystringから漏洩する可能性がある。
  • 対策
    • requestパラメタ
      Requestオブジェクトに機密性の高いパラメタが含まれている場合、
      ClientはRequestオブジェクトをJWEで暗号化すべき。
  • request_uriパラメタ

ユーザ毎のrequest_uriは避けるべき。

  • 永続的なユーザ単位のrequest_uriが使用されている場合、ユーザを識別することが可能。
  • ブラウザの履歴などでコレを観察し、ユーザ活動との関連付けが可能。
  • ある意味では、これはデータ開示でもあり、避けるべき。

参考


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


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2019-06-20 (木) 18:11:00 (28d)