| RFC 9449 | OAuth DPoP | 2023年9月 |
| Fett ほか | 標準化過程 | [Page] |
この文書は、アプリケーションレベルの所有証明メカニズムを通じて OAuth 2.0 トークンを送信者制約するためのメカニズムについて説明する。 このメカニズムにより、アクセストークンおよびリフレッシュトークンを用いた リプレイ攻撃の検出が可能になる。¶
これはインターネット標準化過程の文書である。¶
この文書は、Internet Engineering Task Force (IETF) の成果物である。これは IETF コミュニティの合意を表す。 公開レビューを受けており、Internet Engineering Steering Group (IESG) によって公開が承認されている。インターネット標準に関する 詳細情報は、RFC 7841 の第2節で入手できる。¶
この文書の現在の状態、正誤表、およびフィードバックの提供方法に 関する情報は、 https://www.rfc-editor.org/info/rfc9449 で入手できる。¶
Copyright (c) 2023 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
Demonstrating Proof of Possession (DPoP) は、
OAuth [RFC6749] アクセストークンおよび
リフレッシュトークンを送信者制約するための、アプリケーションレベルのメカニズムである。
これは、HTTP 要求に DPoP ヘッダーを含めることで、クライアントが
公開鍵/秘密鍵ペアの所有を証明できるようにする。
このヘッダーの値は JSON Web Token
(JWT) [RFC7519] であり、認可
サーバーが発行するトークンをクライアントの鍵ペアの公開部分に
バインドできるようにする。そのようなトークンの受信者は、クライアントが
DPoP ヘッダーを通じて保持していることを示した鍵ペアに
トークンがバインドされていることを検証でき、それによって、トークンを提示する
クライアントが秘密鍵も所有しているという一定の保証を提供する。
言い換えると、トークンの正当な提示者は、その鍵ペアの秘密部分を
保持し、その所有を証明する送信者に制約される。¶
ここで規定されるメカニズムは、下位の安全な トランスポート層の要素を利用する、[RFC8705] や [TOKEN-BINDING] などの他の送信者制約トークン方式が利用できない、または望ましくない場合に 使用できる。たとえば、ユーザーエージェントにおける TLS クライアント認証の ユーザー体験が十分でないこと、および HTTP トークン バインディングのサポートがないことにより、OAuth クライアントが Web ブラウザー内で 動的にダウンロードされ実行されるアプリケーション(「シングルページアプリケーション」と 呼ばれることもある)である場合、どちらのメカニズムも使用できない。 さらに、ユーザーのデバイスに直接インストールされ実行されるアプリケーションは、 侵害された、または悪意あるリソースによるトークンの悪用を防ぐ DPoP バインドトークンから恩恵を受けやすい位置にある。 そのようなアプリケーションは、多くの場合、暗号鍵用の専用の保護された ストレージを備えている。¶
DPoP は、採用されるクライアント認証方式に関係なく、
アクセストークンを送信者制約するために使用できるが、DPoP 自体はクライアント認証には使用されない。
DPoP はまた、公開クライアント
(client_id に関連付けられた認証資格情報を持たないクライアント)に発行される
リフレッシュトークンを送信者制約するためにも使用できる。¶
この文書におけるキーワード "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", および "OPTIONAL" は、 ここに示すようにすべて大文字で出現する場合に限り、 BCP 14 [RFC2119] [RFC8174] に記載されているとおりに解釈される。¶
この仕様では、[RFC5234] の Augmented Backus-Naur Form (ABNF) 記法を使用する。¶
この仕様では、"The OAuth 2.0 Authorization Framework" [RFC6749] によって定義される "access token", "refresh token", "authorization server", "resource server", "authorization endpoint", "authorization request", "authorization response", "token endpoint", "grant type", "access token request", "access token response", "client", "public client", および "confidential client" という用語を使用する。¶
"request", "response", "header field", および "target URI" という用語は、[RFC9110] から取り込まれている。¶
"JOSE" および "JOSE Header" という用語は、[RFC7515] から取り込まれている。¶
この文書には、部分的および完全な HTTP メッセージの非規範的な例が含まれる。 一部の例では、長い値の行折り返しを示すために、 [RFC8792] に従って単一の末尾バックスラッシュを使用する。 折り返された行の文字および先頭のスペースは、値の一部ではない。¶
DPoP の主な目的は、トークンの発行時に公開鍵へ バインドし、トークンの使用時に対応する秘密鍵の所有を クライアントに証明させることにより、漏えいまたは盗難されたアクセストークンを 認可されていない、または正当でない当事者が使用することを防ぐことである。 これにより、トークンの正当な送信者は秘密鍵にアクセスできる当事者のみに 制約され、トークンを受け取るサーバーには、その送信者がそれを使用する権限を 正当に持っているという追加の保証が与えられる。¶
したがって、DPoP によって送信者制約されたアクセストークンは、 そのようなトークンを所有する任意の当事者が使用できる典型的な Bearer トークンとは 対照的である。Bearer トークンの意図しない開示を防ぐ保護は一般に存在するものの、 プロトコルまたはソフトウェアスタックの他の層における脆弱性や実装上の問題により、 予期しない漏えい経路が発生してきた(たとえば、Compression Ratio Info-leak Made Easy (CRIME) [CRIME]、Browser Reconnaissance and Exfiltration via Adaptive Compression of Hypertext (BREACH) [BREACH]、 Heartbleed [Heartbleed]、および Cloudflare parser bug [Cloudbleed] を参照)。 OAuth 実装自体に対する多数の公開されたトークン窃取攻撃も存在する ([GitHub.Tokens] は注目度の高い一例にすぎない)。 DPoP は、予期しないトークン漏えいの影響に対する一般的な多層防御を提供する。 ただし、DPoP は安全なトランスポートの代替ではなく、常に HTTPS と併用 MUST する。¶
典型的な OAuth プロトコル相互作用の性質上、
クライアントは、アクセスする保護リソースに対してアクセストークンを開示する必要がある。
[SECURITY-TOPICS]
の攻撃者モデルでは、保護リソースが偽造、悪意あるもの、または侵害されたものであり、
受け取ったトークンを他の保護リソースに対して再生して
不正アクセスを得る場合が説明されている。Audience 制限付きアクセストークン
(たとえば、JWT [RFC7519] の aud
クレームを使用するもの)は、
そのような悪用を防ぐことができる。しかし、実際には、[RFC8707]
のような拡張があるにもかかわらず、
多くのデプロイメントではこれを行うことが非常に煩雑であることが分かっている。
アクセストークンを送信者制約することは、別のエンドポイントでのそのような
トークンリプレイを防ぐための、より堅牢で直接的なメカニズムであり、DPoP は
それを実現するアクセスしやすいアプリケーション層の手段である。¶
クロスサイトスクリプティング (XSS) の可能性により、 ブラウザーベースの OAuth クライアントでは、トークン保護に関して追加の考慮事項が生じる。 最も単純な XSS ベースの攻撃は、攻撃者がトークンを外部に持ち出し、正当なクライアントとは 完全に独立して自ら使用することである。盗まれたアクセストークンは保護リソースアクセスに 使用され、盗まれたリフレッシュトークンは新しいアクセストークンの取得に使用される。 秘密鍵が抽出不可能である場合([W3C.WebCryptoAPI] で可能なように)、 DPoP は、外部に持ち出されたトークンだけでは使用できないようにする。¶
XSS 脆弱性はまた、攻撃者がブラウザーベースのクライアントアプリケーションの コンテキスト内でコードを実行し、クライアントを通じて間接的にトークンを悪用することを可能にする。 その実行コンテキストは署名鍵を利用するアクセスを持つため、トークンと併用する DPoP 証明を生成できる。このアプリケーション層では、一般に XSS を防止する以外に、 この脅威に対する実行可能な防御はほとんどないため、これは DPoP の範囲外と見なされる。¶
ブラウザーベースのクライアントアプリケーションのコンテキストで実行される 悪意ある XSS コードは、将来のタイムスタンプ値を持つ DPoP 証明を作成し、 それらをトークンとともに外部に持ち出す位置にもある。これらの盗まれた成果物は、 後でクライアントアプリケーションとは独立して保護リソースにアクセスするために使用できる。 これを防ぐため、サーバーは、攻撃者が予測できないサーバー選択値(nonce)を 証明に含めるようクライアントに要求することを任意で選択できる。 任意の nonce がない場合でも、事前計算された DPoP 証明の影響は、証明が 保護リソースアクセス時にアクセストークンにバインドされることによってある程度制限される。 まだ存在しないアクセストークンを対象とする証明は実際には作成できないため、 外部に持ち出されたリフレッシュトークンおよび事前計算された証明で取得された アクセストークンは使用不能になる。¶
この仕様によって導入される主なデータ構造は、 以下で詳述するように、HTTP 要求のヘッダーとして送信される DPoP 証明 JWT である。クライアントは、ある公開鍵に対応する秘密鍵の 所有を証明するために DPoP 証明 JWT を使用する。¶
大まかに言えば、DPoP 証明は以下に対する署名である。¶
+--------+ +---------------+ | |--(A)-- Token Request ------------------->| | | Client | (DPoP Proof) | Authorization | | | | Server | | |<-(B)-- DPoP-Bound Access Token ----------| | | | (token_type=DPoP) +---------------+ | | | | | | +---------------+ | |--(C)-- DPoP-Bound Access Token --------->| | | | (DPoP Proof) | Resource | | | | Server | | |<-(D)-- Protected Resource ---------------| | | | +---------------+ +--------+
DPoP を伴う OAuth フロー(任意の nonce なし)の基本手順を、図 1に示す。¶
ここで提示される DPoP メカニズムは、クライアント認証方式ではない。
実際、DPoP の主要なユースケースは、クライアント認証を使用しない公開クライアント
(たとえば、シングルページアプリケーションやユーザーのデバイス上のアプリケーション)である。
それでも、DPoP は private_key_jwt および他のすべての
クライアント認証方式と互換になるよう設計されている。¶
DPoP は、クライアントによって作成され、
DPoP ヘッダーフィールドを使用して HTTP 要求とともに送信される
JWT である DPoP 証明の概念を導入する。
各 HTTP 要求には一意な DPoP 証明が必要である。¶
有効な DPoP 証明は、DPoP 証明 JWT の署名に使用された秘密鍵を クライアントが保持していることをサーバーに示す。これにより、認可サーバーは (第5節で説明するように) 発行したトークンを対応する公開鍵にバインドでき、 リソースサーバーは受け取ったトークンの鍵バインディングを検証できる (第7.1節を参照)。これにより、 当該トークンが秘密鍵にアクセスできないエンティティによって使用されることを防ぐ。¶
DPoP 証明は鍵の所有を示すものであり、それ自体は認証またはアクセス制御の メカニズムではない。第7.1節で説明するように、鍵バインドされたアクセストークンと ともに提示される場合、DPoP 証明は、クライアントがアクセストークンを提示する 正当性について追加の保証を提供する。しかし、有効な DPoP 証明 JWT だけでは、 アクセス制御の判断を行うには十分ではない。¶
DPoP 証明は、以下の要求ヘッダーフィールドを使用して HTTP 要求に含められる。¶
図 2は、 DPoP HTTP ヘッダーフィールドの例を示す。この例では、[RFC8792] に従って "\" による行折り返しを使用している。¶
[RFC9110] によれば、
ヘッダーフィールド名は大文字小文字を区別しないことに注意。
したがって、DPoP, DPOP,
dpop などはいずれも有効で同等のヘッダーフィールド名である。
ただし、ヘッダーフィールド値では大文字小文字が重要である。¶
DPoP HTTP ヘッダーフィールド値は、
第11.2節
of [RFC9110] で定義される token68 構文を
使用し、参照しやすいように図 3に再掲する。¶
DPoP = token68
token68 = 1*( ALPHA / DIGIT /
"-" / "." / "_" / "~" / "+" / "/" ) *"="
DPoP 証明は、クライアントが選択した秘密鍵(下記参照)で (JSON Web Signature (JWS) [RFC7515] を使用して)署名された JWT [RFC7519] である。 DPoP JWT の JOSE Header は、少なくとも以下のパラメーターを含め MUST。¶
typ:
dpop+jwt を持つフィールド。¶
alg:
none または対称アルゴリズム
(Message Authentication Code (MAC))の識別子であっては
MUST NOT ならない。¶
jwk:
DPoP 証明のペイロードは、少なくとも以下のクレームを含め MUST。¶
jti:
jti は、サーバーによるリプレイ検出および防止に使用できる。
第
11.1節を参照。¶
htm:
htu:
iat:
DPoP 証明が、保護リソースアクセスにおけるアクセストークンの 提示と併用される場合(第7節を参照)、 DPoP 証明は以下のクレームも含め MUST。¶
ath:
認証サーバーまたはリソースサーバーが応答内で
DPoP-Nonce HTTP ヘッダーを
提供する場合(第8節および第9節を参照)、DPoP 証明は
以下のクレームも含め
MUST。¶
nonce:
DPoP-Nonce HTTP ヘッダーを通じて提供された最近の nonce。¶
DPoP 証明は、拡張、プロファイル、またはデプロイメント固有の 要件によって定義される他の JOSE Header パラメーターまたはクレームを含んでも MAY よい。¶
図 4は、 図 2の DPoP 証明をデコードした内容を示す概念的な例である。JWT ヘッダーとペイロードの JSON が示されているが、署名部分は省略されている。通常どおり、改行および余分な スペースは、書式設定と読みやすさのために含まれている。¶
{
"typ":"dpop+jwt",
"alg":"ES256",
"jwk": {
"kty":"EC",
"x":"l8tFrhx-34tV3hRICRDY9zCkDlpBhF42UQUfWVAWBFs",
"y":"9VE4jf_Ok_o64zbTTlcuNJajHmt6v9TDVrU0CdvGRDA",
"crv":"P-256"
}
}
.
{
"jti":"-BwC3ESc6acc2lTc",
"htm":"POST",
"htu":"https://server.example.com/token",
"iat":1562262616
}
DPoP 証明の JWT 内容の例
HTTP 要求のうち、HTTP メソッドと URI のみが DPoP JWT に含まれる。したがって、この 2 つのメッセージ部分のみが DPoP 証明によってカバーされる。 この考え方は、HTTP 要求に関する所有証明として妥当なものを提供するために 必要十分な HTTP データだけに署名することである。 HTTP ヘッダーデータの最小限のサブセットのみを使用するこの設計方針は、 HTTP メッセージの正規化を試みることに本質的に伴う大きな困難を 回避するためである。 それにもかかわらず、DPoP 証明は HTTP 要求の他の情報を含むように 拡張できる(第 11.7節も参照)。¶
DPoP 証明を検証するために、受信サーバーは以下を確実にし MUST。¶
DPoP HTTP 要求ヘッダーフィールドが
2 つ以上存在しないこと。¶
typ JOSE Header Parameter が値
dpop+jwt を持つこと。¶
alg JOSE Header Parameter が、登録済みの
非対称デジタル署名アルゴリズム
[IANA.JOSE.ALGS]
を示し、none ではなく、
アプリケーションによってサポートされ、ローカルポリシーに従って受け入れ可能であること。¶
jwk
JOSE Header Parameter に含まれる公開鍵で検証されること。¶
jwk JOSE Header Parameter が秘密鍵を
含まないこと。¶
htm クレームが現在の要求の HTTP メソッドと
一致すること。¶
htu クレームが、query 部分および
fragment 部分を無視して、JWT が受信された HTTP 要求の HTTP URI 値と
一致すること。¶
nonce クレームがサーバー提供の nonce 値と一致すること。¶
iat クレームまたは
nonce クレームを通じたサーバー管理タイムスタンプのいずれかによって
判断され、許容可能なウィンドウ内にあること(第
11.1節を参照)。¶
アクセストークンとともに保護リソースに提示される場合、¶
偽陰性の可能性を低減するため、サーバーは
htu クレームを比較する前に、構文ベースの正規化
(第6.2.2節
of [RFC3986])およびスキームベースの
正規化(第6.2.3節
of [RFC3986])を採用
SHOULD する。¶
これらの検査は任意の順序で実行してよい。¶
DPoP を使用して公開鍵にバインドされたアクセストークンを要求するには、
クライアントは、認可サーバーのトークンエンドポイントにアクセストークン要求を行う際に、
DPoP ヘッダー内で有効な DPoP 証明 JWT を提供し
MUST。
これは、グラント種別に関係なくすべてのアクセストークン要求に適用される
(たとえば、一般的な authorization_code および
refresh_token グラント種別、ならびに JWT 認可グラント
[RFC7523] などの拡張グラント)。
図 5に示す HTTP 要求は、
認可コードグラントを使用し、DPoP ヘッダー内に DPoP 証明 JWT を含む
そのようなアクセストークン要求を例示している。図 5
では、[RFC8792] に従って "\" による行折り返しを使用している。¶
DPoP HTTP ヘッダーフィールドは、有効な
DPoP 証明 JWT を含め
MUST。
DPoP 証明が無効である場合、認可サーバーは
第
5.2節 of [RFC6749] に従って、
error パラメーターの値を
invalid_dpop_proof とするエラー応答を発行する。¶
DPoP 証明の有効性を検査した後でアクセストークンを送信者制約するため、
認可サーバーは、発行されたアクセストークンを DPoP 証明の公開鍵に関連付ける。
これは、第6節で説明するように実現できる。
クライアントに対して、アクセストークンがその DPoP 鍵にバインドされ、
第7.1節で説明するように使用できることを通知するため、
アクセストークン応答には DPoP の token_type を含め
MUST。
図 6に示す例の応答は、そのような
応答を例示している。¶
図
6の例の応答には、以前のアクセストークンが期限切れになったときに
クライアントが新しいアクセストークンを取得するために使用できるリフレッシュトークンが含まれる。
アクセストークンの更新は、認可サーバーのトークンエンドポイントに対して行われる
refresh_token グラント種別を使用するトークン要求である。
すべてのアクセストークン要求と同様に、クライアントは
図 7に示すように、
DPoP 証明を含めることでそれを DPoP 要求にする。図 7では、[RFC8792] に従って "\" による行折り返しを使用している。¶
DPoP をサポートする認可サーバーが、トークンエンドポイントで 有効な DPoP 証明を提示する公開クライアントにリフレッシュトークンを発行する場合、 リフレッシュトークンは対応する公開鍵にバインドされ MUST。 後でリフレッシュトークンが新しいアクセストークンを取得するために提示される際、 そのバインディングは検証され MUST。その結果、そのようなクライアントは、そのリフレッシュトークンを 新しいアクセストークンの取得に使用するたびに、リフレッシュトークンの取得に使用されたものと 同じ鍵に対する DPoP 証明を提示し MUST。 リフレッシュトークンのバインディングの実装詳細は、認可サーバーの裁量に委ねられる。 認可サーバーはリフレッシュトークンの生成と検証の両方を行うため、 バインディングの具体的な詳細には相互運用性上の考慮事項はない。¶
認可サーバーは、DPoP バインドされていないアクセストークンを発行することを選択しても
MAY よい。
これは、[RFC6750] に従ってアクセストークン応答の
token_type パラメーターに Bearer の値を設定することでクライアントに通知される。
リフレッシュトークンも発行される公開クライアントの場合、これはリフレッシュトークンのみを
DPoP バインドする効果があり、保護リソースが DPoP をサポートするよう更新されていない場合でも
セキュリティ態勢を改善できる。¶
アクセストークン応答に DPoP とは異なる
token_type 値が含まれる場合、DPoP によって提供される
アクセストークン保護は与えられない。この保護がアプリケーションのセキュリティにとって
重要であると見なされる場合、クライアントはこの応答を破棄し
MUST。そうでない場合、クライアントは通常の OAuth 相互作用と同様に続行してよい。¶
機密クライアント(認可サーバーとの間で認証資格情報を確立しているもの)に 発行されるリフレッシュトークンは、既に別の既存メカニズムによって送信者制約されているため、 DPoP 証明の公開鍵にはバインドされない。 OAuth 2.0 Authorization Framework [RFC6749] は、 認可サーバーがリフレッシュトークンをそれが発行されたクライアントにバインドすること、 および機密クライアントがリフレッシュトークンを提示する際に認可サーバーに対して認証することを 既に要求している。その結果、そのようなリフレッシュトークンは、 クライアント識別子および関連する認証要件によって送信者制約される。 この既存の送信者制約メカニズムは、特定の公開鍵に直接バインドするよりも柔軟である (たとえば、リフレッシュトークンを無効化せずにクライアントの資格情報ローテーションを可能にする)。¶
この文書は、DPoP の一般的なサポートと、認可サーバーが DPoP 証明 JWT 用に
サポートする具体的な JWS alg 値を通知するため、以下の認可サーバー
メタデータ [RFC8414] パラメーターを導入する。¶
dpop_signing_alg_values_supported:
alg 値([IANA.JOSE.ALGS] レジストリ由来)のリストを含む
JSON 配列。¶
Dynamic Client Registration Protocol [RFC7591] は、OAuth 2.0 クライアントメタデータを 認可サーバーに動的に登録するための API を定義する。 [RFC7591] によって定義されるメタデータ、 およびそれに登録された拡張は、Dynamic Client Registration Protocol が使用されていない場合でも、 認可サーバー実装に有用なクライアントの一般的なデータモデルも含意する。 そのような実装では、通常、クライアント構成を管理するための何らかのユーザーインターフェイスが 利用可能である。¶
この文書は、クライアントが認可サーバーからトークンを要求する際に 常に DPoP を使用することを示すため、以下のクライアント登録メタデータ [RFC7591] パラメーターを導入する。¶
dpop_bound_access_tokens:
false である。¶
値が true の場合、認可サーバーは、
DPoP ヘッダーを含まないそのクライアントからのトークン要求を拒否し
MUST。¶
リソースサーバーは、アクセストークンが DPoP バインドされているかどうかを 確実に識別し、DPoP 証明の公開鍵へのバインディングを検証するために十分な情報を 確認でき MUST(第7.1節を参照)。 そのようなバインディングは、保護リソースがアクセスできる方法で公開鍵をトークンに 関連付けることによって実現される。たとえば、第6.1節で 説明される構文を使用して、発行されたアクセストークンに JWK ハッシュを直接埋め込む方法や、 第6.2節で説明するようにトークンイントロスペクションを 通じて行う方法がある。 公開鍵をアクセストークンに関連付ける他の方法も、認可サーバーと保護リソースの合意に従って 可能である。ただし、それらはこの仕様の範囲外である。¶
DPoP をサポートするリソースサーバーは、DPoP 証明の公開鍵が アクセストークンにバインドされたものと一致することを保証し MUST。¶
アクセストークンが JWT [RFC7519]
として表現される場合、
公開鍵情報は、ここで定義される jkt 確認方法メンバーを使用して表される。
JWT 内で公開鍵のハッシュを伝達するため、この仕様は、cnf クレームの下で
使用する以下の JWT Confirmation Method [RFC7800]
メンバーを導入する。¶
jkt:
jkt メンバーの値は、アクセストークンがバインドされる
DPoP 公開鍵(JWK 形式)の JWK SHA-256 Thumbprint
([RFC7638] に従う)を
base64url エンコード([RFC7515] で定義)したもので
MUST ある。¶
図 8の以下の例の JWT は、
図 9に示すデコード済み JWT ペイロードを伴い、
jkt JWK Thumbprint 確認方法メンバーを持つ cnf クレームを含む。
これらの例における jkt 値は、第5節の例で示された DPoP 証明の公開鍵のハッシュである。
この例では、[RFC8792] に従って "\"
による行折り返しを使用している。¶
eyJhbGciOiJFUzI1NiIsImtpZCI6IkJlQUxrYiJ9.eyJzdWIiOiJzb21lb25lQGV4YW1\ wbGUuY29tIiwiaXNzIjoiaHR0cHM6Ly9zZXJ2ZXIuZXhhbXBsZS5jb20iLCJuYmYiOjE\ 1NjIyNjI2MTEsImV4cCI6MTU2MjI2NjIxNiwiY25mIjp7ImprdCI6IjBaY09DT1JaTll\ 5LURXcHFxMzBqWnlKR0hUTjBkMkhnbEJWM3VpZ3VBNEkifX0.3Tyo8VTcn6u_PboUmAO\ YUY1kfAavomW_YwYMkmRNizLJoQzWy2fCo79Zi5yObpIzjWb5xW4OGld7ESZrh0fsrA
{
"sub":"someone@example.com",
"iss":"https://server.example.com",
"nbf":1562262611,
"exp":1562266216,
"cnf":
{
"jkt":"0ZcOCORZNYy-DWpqq30jZyJGHTN0d2HglBV3uiguA4I"
}
}
"OAuth 2.0 Token Introspection" [RFC7662] は、 保護リソースがアクセストークンのアクティブ状態について認可サーバーに問い合わせるための方法を定義する。 保護リソースは、トークンに関するメタ情報も判断する。¶
DPoP バインドされたアクセストークンの場合、トークンがバインドされている公開鍵の
ハッシュは、トークンイントロスペクション応答内のメタ情報として保護リソースに伝達される。
このハッシュは、第6.1節で説明した
JWK Thumbprint 確認方法と同じ jkt メンバー構造を持つ
cnf 内容を、イントロスペクション応答 JSON のトップレベルメンバーとして
使用して伝達される。リソースサーバーはイントロスペクション要求とともに DPoP 証明を
送信せず、認可サーバーはイントロスペクションエンドポイントでアクセストークンの DPoP
バインディングを検証しないことに注意。むしろ、リソースサーバーはイントロスペクション応答の
データを使用して、アクセストークンバインディングを自らローカルで検証する。¶
token_type メンバーがイントロスペクション応答に含まれる場合、
それは値 DPoP を含め
MUST。¶
図 10の例のイントロスペクション要求と、 図 11の対応する応答は、 図 6で発行された例の DPoP バインドアクセストークンに対するイントロスペクション交換を例示している。¶
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
{
"active": true,
"sub": "someone@example.com",
"iss": "https://server.example.com",
"nbf": 1562262611,
"exp": 1562266216,
"cnf":
{
"jkt": "0ZcOCORZNYy-DWpqq30jZyJGHTN0d2HglBV3uiguA4I"
}
}
DPoP 保護リソースへの要求は、第4節に従う DPoP 証明と、
第7.1節で説明するアクセストークンの両方を含め
MUST。
DPoP 証明は、関連付けられたアクセストークンの有効なハッシュを持つ
ath クレームを含め
MUST。¶
このようにトークン値を証明にバインドすることで、証明が異なる要求間で
複数の異なるアクセストークン値とともに使用されることを防ぐ。
たとえば、クライアントが 2 人の異なるリソース所有者にバインドされたトークン AT1 と AT2 を保持し、
認可サーバーと通信する際に同じ鍵を使用している場合、これらのトークンが入れ替えられる可能性がある。
それをバインドする ath フィールドがなければ、AT1 に適用された取得済み署名が
代わりに AT2 とともにリプレイされ、意図された要求の権限とアクセスが変更される可能性がある。
同じクライアントとリソース所有者の組み合わせ内でローテーションされたアクセストークンについても、
この同じ置換防止は維持される。ローテーションされたトークン値には、新しい証明の計算が必要になる。
このバインディングはさらに、アクセストークンとともに使用することを意図した証明が
アクセストークンなしでは使用できず、その逆も同様であることを保証する。¶
リソースサーバーは、提示されたトークン値のハッシュを計算し、
第4.3節で説明するように、それが
ath フィールド内のハッシュ値と同じであることを検証する必要がある。
ath フィールド値は DPoP 証明の署名によってカバーされるため、
これを含めることで、アクセストークン値は署名を生成するために使用された鍵の保持者にバインドされる。¶
ath フィールドだけでは、DPoP 証明のリプレイを防止したり、
証明が提示される要求へのバインディングを提供したりしないことに注意。
したがって、htm や htu などの含まれるメッセージパラメーターだけでなく、
証明の時間ウィンドウも検査することが依然として重要である。¶
DPoP バインドアクセストークンは、
第11.6.2節 of
[RFC9110] に従い、DPoP の認証スキームを用いて
Authorization 要求ヘッダーフィールドで送信される。
DPoP スキームの Authorization
ヘッダーフィールドの構文は、資格情報について
第11.2節
of [RFC9110] で定義される token68 構文を使用し、
参照しやすいように以下に再掲する。
DPoP 認証スキーム資格情報の ABNF 記法構文は次のとおりである。¶
token68 = 1*( ALPHA / DIGIT /
"-" / "." / "_" / "~" / "+" / "/" ) *"="
credentials = "DPoP" 1*SP token68
そのようなアクセストークンについて、リソースサーバーは、
HTTP 要求の DPoP ヘッダーフィールド内で DPoP 証明も受信されていることを検査し、
第4.3節の規則に従って DPoP 証明を検査し、
かつ 第6節に従って、DPoP 証明の公開鍵がアクセストークンの
バインド先である公開鍵と一致することを検査し
MUST。¶
リソースサーバーは、すべての検査が成功しない限り、リソースへのアクセスを許可しては MUST NOT ならない。¶
図 13は、
Authorization ヘッダー内に DPoP バインドアクセストークンを含み、
DPoP ヘッダー内に DPoP 証明を含む保護リソースへの要求例を示す。
この例では、[RFC8792] に従って "\" による行折り返しを使用している。
図 14は、その DPoP
証明のデコード済み内容を示す。JWT ヘッダーとペイロードの JSON が示されているが、
署名部分は省略されている。通常どおり、改行とインデントは書式設定と読みやすさのために
含まれている。¶
{
"typ":"dpop+jwt",
"alg":"ES256",
"jwk": {
"kty":"EC",
"x":"l8tFrhx-34tV3hRICRDY9zCkDlpBhF42UQUfWVAWBFs",
"y":"9VE4jf_Ok_o64zbTTlcuNJajHmt6v9TDVrU0CdvGRDA",
"crv":"P-256"
}
}
.
{
"jti":"e1j3V_bKic8-LAEB",
"htm":"GET",
"htu":"https://resource.example.org/protectedresource",
"iat":1562262618,
"ath":"fUHyO2r2Z3DZ53EsNrWBb0xWXoaNy59IiKCAqksmQEo"
}
DPoP 証明 JWT のデコード済み内容
DPoP 認証を必要とする保護空間内の保護リソースへの要求を受信した際、
要求が有効な資格情報を含まない場合、またはアクセスに十分なアクセストークンを含まない場合、
サーバーは DPoP 認証情報を提供するようクライアントにチャレンジで応答できる。
そのようなチャレンジは、401 (Unauthorized) 応答ステータスコード
([RFC9110], 第
15.5.2節)および WWW-Authenticate ヘッダーフィールド
([RFC9110], 第
11.6.1節)を使用して行われる。
サーバーは、他の条件への応答として WWW-Authenticate ヘッダーを含めても
MAY よい。¶
そのようなチャレンジでは、次のとおりである。¶
DPoP である。¶
realm は、
[RFC9110], 第
11.5節 で説明される方法で保護範囲を示すために含めても
MAY よい。¶
scope 認証パラメーターは、
[RFC6750], 第
3節 で定義されるように含めても
MAY よい。¶
error パラメーター
([RFC6750], 第
3節)は、要求にアクセストークンが含まれていたが認証に失敗した場合に、
要求が拒否された理由を示すために含める
SHOULD。
[RFC6750], 第
3.1節 で説明されるエラーパラメーター値は適しており、
拡張によって定義される適切な値も同様である。
値 use_dpop_nonce は、後続の要求の DPoP 証明で nonce が必要であることを
通知するために、第9節で説明するように
使用できる。さらに、invalid_dpop_proof は、
第4.3節の基準に基づいて DPoP
証明自体が無効と判断されたことを示すために使用される。¶
error_description パラメーター
([RFC6750], 第
3節)は、エンドユーザーに表示することを意図しない、人間が読める開発者向けの説明を
提供するために、error パラメーターとともに含めても
MAY よい。¶
algs パラメーターは、
DPoP 証明 JWT に対して受け入れ可能な JWS アルゴリズムをクライアントに通知するために
含める
SHOULD。
パラメーターの値は、空白で区切られた JWS alg (Algorithm)
ヘッダー値のリストである([RFC7515], 第
4.1.1節)。¶
図 15は、認証なしの保護リソース要求に対する応答を示す。¶
図 16は、アクセストークン内の DPoP バインディングの確認に失敗したために 拒否された保護リソース要求に対する応答を示す。図 16では、[RFC8792] に従って "\" による行折り返しを使用している。¶
Cross-Origin Resource Sharing (CORS)
[WHATWG.Fetch] を使用する
ブラウザーベースのクライアントアプリケーションは、既定では CORS セーフリストに含まれる
応答 HTTP ヘッダーにのみアクセスできることに注意。
アプリケーションが WWW-Authenticate HTTP 応答ヘッダー値を取得して使用できるようにするには、
サーバーは Access-Control-Expose-Headers 応答ヘッダーリスト値に
WWW-Authenticate を含めることによって、それをアプリケーションに利用可能にする必要がある。¶
この認証スキームは、オリジンサーバー認証専用である。
したがって、この認証スキームは
Proxy-Authenticate または Proxy-Authorization ヘッダーフィールドとともに使用しては
MUST NOT ならない。¶
この認証スキームの Authorization ヘッダーフィールドの構文は、
第2.1節 of
[RFC6750] で定義される
Bearer スキームの使用方法に従うことに注意。
これは [RFC9110] の推奨される資格情報構文ではないが、
そこにある一般的な認証フレームワークと互換であり、Bearer スキームとの
一貫性と親しみやすさのために使用される。¶
DPoP スキームと
Bearer
スキームの両方を同時にサポートする保護リソースは、DPoP バインドされたアクセストークンの
ダウングレードされた使用を防ぐため、Bearer トークンに対する評価プロセスの実行方法を更新する必要がある。
具体的には、そのような保護リソースは、[RFC6750] に従って Bearer
トークンとして受信した
DPoP バインドアクセストークンを拒否し
MUST。¶
第11.6.1節 of [RFC9110]
は、保護リソースが 401 (Unauthorized) 応答の
WWW-Authenticate ヘッダーフィールドで複数の認証スキーム
(すなわち Bearer および DPoP)のサポートを示すことを許可している。¶
[RFC6750] のみをサポートし、DPoP
を認識しない保護リソースは、
おそらく DPoP バインドアクセストークンを Bearer トークンとして受け入れるだろう
(JWT [RFC7519] は認識できないクレームを
無視するよう述べており、Introspection [RFC7662]
は、他のパラメーターが存在し得る一方で、その存在に関する機能要件を置いておらず、
[RFC6750] は、有効性に関係するためアクセストークンの内容について
実質的に何も述べていない)。
そのため、クライアントは、保護リソースから
WWW-Authenticate: Bearer チャレンジを受け取った際に、DPoP バインド
アクセストークンを Bearer スキームを使用して送信できる
(または、保護リソースの機能を事前に知っている場合に DPoP バインドアクセストークンを送信できる)。
この効果により、保護リソースでの DPoP サポートへの段階的アップグレード、
または混在したトークン種別サポートを持つ保護リソースの長期デプロイメントの
運用が簡素化される可能性が高い。¶
Bearer および
DPoP スキームの両方をサポートする保護リソースが、複数の
WWW-Authenticate チャレンジで応答することを選択する場合、
どのチャレンジが実際のエラー情報を伝えるべきかに注意を払うべきである。
次の規則に従うことが
RECOMMENDED される。¶
DPoP 証明を含む認可は、サーバーによる
jti、iat、および nonce クレームの適用方法によっては
冪等ではない場合がある。その結果、以前は冪等であった保護リソースへのすべての要求は、
もはや冪等ではなくなる可能性がある。
一般に一時的と理解される HTTP エラーへの応答として冪等な要求を再試行する場合でも、
クライアントが一意な DPoP 証明を生成することが
RECOMMENDED される。¶
頻繁なネットワークエラーに遭遇するクライアントは、 より厳格な nonce 検証実装を持つサーバーとやり取りする際に、追加の課題に直面する可能性がある。¶
この節では、DPoP 証明の有効期間を制限するために使用できる、 サーバーが提供する不透明な nonce を用いるメカニズムを規定する。 そのようなメカニズムを採用しない場合、クライアントを制御する悪意ある当事者 (エンドユーザーを含む可能性がある)は、 任意に遠い将来に使用するための DPoP 証明を作成できる。¶
認可サーバーによって提供された nonce 値を DPoP 証明に含めることは、 DPoP 証明の有効期間を制限するために認可サーバーが使用しても MAY よい。 サーバーは、新しい DPoP nonce チャレンジをいつ発行するか、 およびそれが必要かどうかを判断し、それによって後続の DPoP 証明で nonce 値の使用を要求する。 サーバーがその判断を行うためのロジックは、この文書の範囲外である。¶
認可サーバーは、送信される DPoP 証明にクライアントが含める nonce 値を
提供しても MAY よい。
この場合、認可サーバーは nonce を含まない要求に対して、
use_dpop_nonce をエラーコード値として使用し、
第5.2節 of [RFC6749] に従って HTTP 400 (Bad Request)
エラー応答で応答する。認可サーバーは、後続の要求を送信するときに使用する nonce 値を
提供するため、応答に DPoP-Nonce HTTP ヘッダーを含める。
Nonce 値は予測不可能で
MUST ある。
nonce の不一致があった場合に新しい nonce 値を提供するときにも、
同じエラーコードが使用される。
クライアントは通常、nonce 値を伴う use_dpop_nonce エラーを受け取ると、
提供された新しい nonce 値で要求を再試行する。¶
たとえば、認可サーバーが nonce を要求しているときに nonce を含まない
トークン要求への応答として、
認可サーバーは、DPoP 証明に含める nonce 値を提供するために、
次のような DPoP-Nonce 値で応答できる。¶
その他の HTTP ヘッダーおよび JSON フィールドもエラー応答に含めても
MAY よいが、
DPoP-Nonce ヘッダーは 2 つ以上あっては
MUST NOT ならない。¶
nonce を受信すると、クライアントは、提供された nonce 値を
DPoP 証明の nonce クレームに含めた DPoP 証明を使用して、
トークン要求を再試行することが期待される。
そのような nonce を含む DPoP 証明のエンコードされていない JWT ペイロードの例を以下に示す。¶
{
"jti": "-BwC3ESc6acc2lTc",
"htm": "POST",
"htu": "https://server.example.com/token",
"iat": 1562262616,
"nonce": "eyJ7S_zG.eyJH0-Z.HX4w-7v"
}
nonce はクライアントに対して不透明である。¶
DPoP 証明内の nonce クレームが、
認可サーバーからクライアントに最近提供された nonce と正確に一致しない場合、
認可サーバーは要求を拒否し
MUST。
拒否応答には、後続の要求で使用する新しい nonce 値を提供する
DPoP-Nonce HTTP ヘッダーを含めても
MAY よい。¶
その意図は、クライアントは 1 つの nonce 値のみを保持すればよく、 サーバーは最近の nonce のウィンドウを保持すればよいということである。 とはいえ、一時的な状況により、サーバーとクライアントに保存された nonce 値が 異なる場合がある。 しかし、この状況は自己修正される。 任意の拒否メッセージで、サーバーはクライアントに使用してほしい nonce 値を クライアントへ送信でき、クライアントはその nonce 値を保存してそれで要求を再試行できる。 クライアントやサーバーが保存している nonce 値を破棄した場合でも、 失敗した要求への応答または再試行時に新しい nonce 値を伝達できるため、 その状況も自己修正される。¶
CORS [WHATWG.Fetch]
を使用するブラウザーベースの
クライアントアプリケーションは、既定では CORS セーフリストに含まれる応答 HTTP ヘッダーにのみ
アクセスできることに注意。
アプリケーションが DPoP-Nonce HTTP 応答ヘッダー値を取得して使用できるようにするには、
サーバーは Access-Control-Expose-Headers 応答ヘッダーリスト値に
DPoP-Nonce を含めることによって、それをアプリケーションに利用可能にする必要がある。¶
[RFC6749] で使用される ABNF における nonce 構文 (scope-token 構文と同じ)を以下に示す。¶
nonce = 1*NQCHAR
クライアントが使用する新しい nonce 値をいつ提供するかは、 認可サーバーに委ねられる。 クライアントは、認可サーバーが新しい nonce 値を提供するまで、 既存の提供済み nonce を DPoP 証明で使用することが期待される。¶
認可サーバーは、最初の nonce が提供されたのと同じ方法、
すなわち応答内の DPoP-Nonce HTTP ヘッダーを使用して、
新しい nonce を提供しても
MAY よい。
DPoP-Nonce HTTP ヘッダーフィールドは、第8.1節で定義される nonce 構文を使用する。
これが発生するたびに、追加のプロトコル往復が必要になる。¶
新しい nonce 値を提供する、より効率的な方法も定義されている。
それは、前回の要求に対する HTTP 200 (OK) 応答に
DPoP-Nonce HTTP ヘッダーを含めることである。
クライアントは、認可サーバーが新しい nonce を提供するまで、
次のトークン要求およびすべての後続のトークン要求で、提供された新しい nonce 値を使用し
MUST。¶
DPoP-Nonce HTTP ヘッダーを含む応答は、
後続の要求を処理するために応答が使用され、その結果として古い nonce 値が
使用されることを防ぐため、キャッシュ不可にすべきである
(たとえば、GET 要求への応答で Cache-Control: no-store を使用する)。¶
新しい nonce 値を提供する 200 OK 応答の例を以下に示す。¶
リソースサーバーも、自分たちに送信される DPoP 証明に含める nonce 値を
提供することを選択できる。
それらは、第8節および第8.2節で説明されるように、認可サーバーと同じ方法で
DPoP-Nonce ヘッダーを使用して nonce を提供する。
エラー通知は、第7.1節で説明されるように実行される。
リソースサーバーは、これを実現するために、
WWW-Authenticate: DPoP 値および DPoP-Nonce 値を伴う
HTTP 401 (Unauthorized) エラーコードを使用する。¶
たとえば、リソースサーバーが nonce を要求しているときに nonce なしの
リソース要求への応答として、
リソースサーバーは、DPoP 証明に含める nonce 値を提供するために、
次のような DPoP-Nonce 値で応答できる。
以下の例では、[RFC8792] に従って "\" による行折り返しを使用している。¶
認可サーバーとリソースサーバーによって提供される nonce は異なり、 nonce はそれを発行したサーバーによってのみ受け入れられるため、 互いに混同すべきではないことに注意。 同様に、クライアントが複数の認可サーバーやリソースサーバーを使用する場合、 それらのいずれかによって発行された nonce は、発行元サーバーでのみ使用すべきである。 開発者はまた、DPoP nonce を OpenID Connect [OpenID.Core] ID Token nonce と 混同しないよう注意すべきである。¶
クライアントの所有証明鍵に発行された認可コードをバインドすることで、
認可フロー全体のエンドツーエンドのバインディングを可能にできる。
この仕様は、この目的のために dpop_jkt 認可要求パラメーターを定義する。
dpop_jkt 認可要求パラメーターの値は、
SHA-256 ハッシュ関数を使用した所有証明公開鍵の
JWK Thumbprint [RFC7638] であり、
これは 第6.1節で定義される jkt
確認方法に使用される値と同じである。¶
トークン要求を受信したとき、認可サーバーは DPoP 証明内の
所有証明公開鍵の JWK Thumbprint を計算し、それが認可要求内の
dpop_jkt パラメーター値と一致することを検証する。
一致しない場合、要求を拒否し
MUST。¶
dpop_jkt 認可要求パラメーターを使用する認可要求の例を
以下に示し、[RFC8792] に従って "\" による行折り返しを使用している。¶
dpop_jkt 認可要求パラメーターの使用は
OPTIONAL である。
dpop_jkt 認可要求パラメーターは、認可コードインジェクションへの対策として
[SECURITY-TOPICS]
によって推奨される Proof Key for Code Exchange (PKCE) [RFC7636] と組み合わせて使用しても
MAY よいことに注意。
dpop_jkt 認可要求パラメーターは、各認可要求に一意な DPoP 鍵が使用される場合にのみ、
類似の保護を提供する。¶
DPoP では、異なるエンドポイントでのトークンリプレイの防止 (第2節を参照)は、 [RFC6125] に従うサーバー認証と、 DPoP 証明の特定の URI および HTTP メソッドへのバインディングによって達成される。 しかし、DPoP は、OAuth Mutual TLS [RFC8705] や OAuth Token Binding [TOKEN-BINDING] などの TLS ベースの方式とは、やや異なる保護の性質を持つ (第11.1節および第11.7節も参照)。 TLS ベースのメカニズムは、TLS 層とアプリケーション層の緊密な統合を活用して、 強力なメッセージ完全性、真正性、およびリプレイ保護を実現できる。¶
攻撃者が DPoP 証明 JWT を入手できた場合、 攻撃者は同じエンドポイントでそのトークンをリプレイできる可能性がある (HTTP エンドポイントおよびメソッドは JWT 内のそれぞれのクレームによって強制される)。 これを制限するため、サーバーは DPoP 証明を、その作成後の限られた時間 (望ましくは秒または分の単位の比較的短い期間)に限って受け入れ MUST。¶
ターゲット URI のコンテキストにおいて、サーバーは、
それぞれの DPoP 証明 JWT が受け入れられる時間ウィンドウの間、
各 DPoP 証明の jti 値を保存できる。
これにより、同じ DPoP 証明の複数回使用を防止できる。
以前にその jti 値が確認された同じ URI への HTTP 要求は拒否される。
厳格に適用される場合、そのような単回使用検査は DPoP 証明リプレイに対して
非常に強力な保護を提供するが、実際には常に実現可能とは限らない。
たとえば、単一のエンドポイントの背後にある複数のサーバーが共有状態を持たない場合である。¶
メモリ枯渇攻撃を防ぐため、jti 値を追跡するサーバーは、
不必要に大きい jti 値を持つ DPoP 証明 JWT を拒否するか、
そのハッシュのみを保存すべきである。¶
注: クロックオフセットに対応するため、サーバーは、
iat 時刻が妥当に近い将来(秒または分の単位)である DPoP 証明を
受け入れても MAY よい。
サーバーとクライアント間のクロックスキューは大きくなる可能性があるため、
サーバーは、クライアント提供の iat 時刻をサーバー時刻と比較するのではなく、
サーバー時刻を含むサーバー提供 nonce 値を使用して DPoP 証明の有効期間を制限しても
MAY よい。この方法で作成された nonce は、任意に大きなクロックスキューが
ある場合でも同じ結果をもたらす。¶
サーバー提供 nonce は、DPoP 証明リプレイが成功する可能性を
さらに低減する有効な手段である。
暗号学的 nonce とは異なり、クライアントが同じ
nonce を複数回使用し、サーバーが同じ nonce を複数回受け入れることは許容される。
nonce の有効期間中に jti 値が追跡され、重複が拒否される限り、
トークンリプレイの追加リスクはない。¶
クライアントを制御する攻撃者は、DPoP 証明内の iat 値を選択し、
所有証明鍵で署名させることによって、特定のエンドポイント用の DPoP 証明を
任意に遠い将来まで事前生成できる。
そのような攻撃者の 1 人は、クライアントの正当なユーザーである人物であることに注意。
ユーザーは、DPoP 証明を事前生成し、それらが生成された所有証明鍵を持つマシンから
外部に持ち出して、その鍵を持たない別のマシンにコピーする可能性がある。
たとえば、銀行員が銀行のコンピューター上で DPoP 証明を事前生成し、
将来使用するために別のマシンにコピーすることで、銀行の監査管理を回避する可能性がある。
DPoP 証明を事前生成して外部に持ち出せる場合、
DPoP プロトコル相互作用で実際に証明されているのは、
所有証明鍵の所有ではなく、DPoP 証明の所有である。¶
攻撃者が予測できないサーバー提供 nonce 値の使用により、 この攻撃を防止できる。 サーバーは、自ら選択した時点で新しい nonce 値を提供することで、 DPoP 証明の有効期間を制限し、 事前生成された DPoP 証明が使用されることを防止できる。 サーバー提供 nonce が使用される場合、単なる DPoP 証明の所有ではなく、 所有証明鍵の所有が示されていることになる。¶
ath クレームは、事前生成された DPoP 証明の使用を
アクセストークンの有効期間に制限する。
nonce メカニズムを利用しないデプロイメントは、長寿命の DPoP 制約付きアクセストークンを
発行すべきでは
SHOULD NOT なく、
代わりに短寿命のアクセストークンとリフレッシュトークンを使用することが望ましい。
攻撃者がリフレッシュトークンを使用して新しいアクセストークンを取得するための DPoP 証明を
事前生成できたとしても、新たに発行されたアクセストークンを使用するための DPoP 証明を
現実的に事前生成することはできない。¶
DPoP nonce がクライアントに提供されている場合、
サーバーは nonce クレームなしの DPoP 証明を受け入れては
MUST NOT ならない。¶
攻撃者がクライアントの実行コンテキスト内でコードを実行できる場合、 DPoP のセキュリティはもはや保証されない。 信頼されないコードの実行につながる Web アプリケーションの一般的な問題は、 XSS およびリモートコード取り込み攻撃である。¶
DPoP に使用される秘密鍵が、ハードウェアまたはソフトウェアの セキュリティモジュールなど、エクスポートできない方法で保存されている場合、 攻撃者は鍵を外部に持ち出し、任意の DPoP 証明を作成するために使用することはできない。 しかし、攻撃者は、クライアントがオンラインである限り新しい DPoP 証明を作成でき、 それらの証明を(それぞれのトークンとともに)被害者のデバイス上、 または攻撃者が制御するデバイス上で使用して、サーバーに受け入れられる任意の要求を 送信できる。¶
クライアントがオフラインのときでも要求を送信するため、 攻撃者は将来のタイムスタンプを使用して DPoP 証明を事前計算し、 これらをアクセストークンまたはリフレッシュトークンとともに外部に持ち出そうとする可能性がある。¶
攻撃者はさらに、トークンエンドポイントから発行されたトークンを、 攻撃者が制御する鍵ペアに関連付けようとする可能性がある。 これを達成する 1 つの方法は、たとえば暗号 API を置き換えることで既存コードを変更することである。 もう 1 つの方法は、iframe 内でクライアントと認可サーバーの間の新しい認可グラントを 開始することである。このグラントは「サイレント」である必要があり、すなわちユーザーとの 相互作用を要求しない必要がある。クライアントのオリジンで実行されるコードにより、 攻撃者は結果として得られる認可コードにアクセスでき、それを使用して、 自分の DPoP 鍵をトークンエンドポイントから返されるトークンに関連付けることができる。 その後、攻撃者は、クライアントがオフラインであっても、自分のデバイスで結果のトークンを 使用できる。¶
したがって、DPoP が使用される場合でも、信頼されないコードの実行から クライアントを保護することは極めて重要である。 安全なコーディングプラクティスに加えて、Content Security Policy [W3C.CSP] は XSS に対する第2の防御層として使用できる。¶
署名付き DPoP 証明 JWT を受け入れるサーバーは、
攻撃者が他の目的のために作成された JWT を使用できないようにするため、
JWT のヘッダー内の typ フィールドが dpop+jwt であることを検証し
MUST。¶
実装者は、DPoP 証明の署名に使用できるのが、
安全と見なされる非対称デジタル署名アルゴリズム(ES256 など)のみであることを
保証し
MUST。特に、
アルゴリズム none は許可しては
MUST NOT ならない。¶
DPoP は、要求のペイロードまたはヘッダーの完全性を保証しない。 DPoP 証明には HTTP URI とメソッドのクレームのみが含まれ、 たとえばメッセージ本文や一般的な要求ヘッダーは含まれない。¶
これは DPoP を使いやすく保つことを意図した設計上の判断であるが、 説明したように、攻撃者がメッセージ内容やヘッダーを変更できる場合、 DPoP はリプレイ攻撃を受けやすくなる可能性がある。 多くの構成では、TLS によって提供されるメッセージ完全性と機密性で、 十分な保護レベルを提供できる。¶
注: 要求の他の部分をカバーする署名はこの仕様の範囲外であるが、 署名される追加情報を DPoP 証明に追加できる。¶
第6節で規定される、 アクセストークンの DPoP 公開鍵へのバインディングは、 公開鍵の JWK 表現の暗号学的ハッシュを使用する。 これは、同じハッシュ出力値を生成する別の鍵を見つけたり作成したりすることを 計算上不可能にするのに十分な第二原像耐性をハッシュ関数が持つことに依存する。 SHA-256 ハッシュ関数は、上述の要件を満たしつつ広く利用可能であるため使用された。¶
同様に、DPoP 証明のアクセストークンへのバインディングは、
DPoP 証明内の ath クレームの値として、そのアクセストークンのハッシュを使用する
(第4.2節を参照)。
これは、アクセストークンを確実に識別するのに十分に一意であるハッシュ値に依存する。
SHA-256 の衝突耐性はその要件を満たす。¶
ここで定義される jkt 確認方法メンバー、
ath JWT クレーム、および dpop_jkt 認可要求パラメーターはすべて、
SHA-256 ハッシュ関数の出力を値として使用する。
この仕様で単一のハッシュ関数を使用することは意図的なものであり、
パラメーター化されたアルゴリズム俊敏性スキームの実装およびデプロイにおける
一般的な誤りから生じる可能性のあるセキュリティおよび相互運用性の問題を避け、
単純さを目指したものである。
しかし、将来の状況が変化し、SHA-256 がこの仕様の要件に不十分となる場合、
異なるハッシュ関数の使用は排除されない。
その必要が生じた場合、この仕様を更新する短い仕様が作成されることが期待される。
適切なハッシュ関数の出力を値として使用し、その仕様はおそらく新しい確認方法メンバー、
新しい JWT クレーム、および新しい認可要求パラメーターを定義するだろう。
これらの項目は、この仕様によって定義されるより大きなプロトコルの同じメッセージ構造と
フローにおいて、それぞれ対応する既存項目の代わりに、または並行して使用される。¶
DPoP がクライアント認証とともに使用される場合、 それは同じ TLS トンネル内で同時に存在することによってのみ認証にバインドされる。 DPoP 証明は暗号学的に認証へ直接バインドされていないため、 認証または DPoP メッセージがトンネル内にコピーされた可能性がある。 DPoP に URI を含めることでこのリスクの一部を部分的に緩和できるが、 認証メカニズムを変更して認証と DPoP の間に暗号学的バインディングを提供することで、 より良い保護が提供される可能性がある。 しかし、認証メカニズムの変更またはその他の手段によって認証との追加バインディングを 提供することは、この仕様の範囲外である。¶
IANA は、[RFC6749] によって 確立された "OAuth Access Token Types" レジストリ [IANA.OAuth.Params] に、以下のアクセストークン種別を 登録した。¶
IANA は、[RFC6749] によって 確立された "OAuth Extensions Error" レジストリ [IANA.OAuth.Params] に、以下のエラー値を 登録した。¶
IANA は、[RFC6749] によって 確立された "OAuth Parameters" レジストリ [IANA.OAuth.Params] に、以下の認可要求パラメーターを 登録した。¶
IANA は、[RFC9110], 第 16.4.1節 によって確立された "HTTP Authentication Schemes" レジストリ [IANA.HTTP.AuthSchemes] に、以下のスキームを登録した。¶
IANA は、application/dpop+jwt メディアタイプを、
DPoP JWT であることを示すために、
[RFC6838] で説明される方法で、
"Media Types" レジストリ [IANA.MediaTypes] に登録した
[RFC2046]。¶
IANA は、[RFC7800] によって
確立された "JWT Confirmation Methods" レジストリ
[IANA.JWT] に、以下の JWT cnf
メンバー値を
登録した。¶
IANA は、[RFC7519] によって 確立された "JSON Web Token Claims" レジストリ [IANA.JWT] に、以下の Claims を 登録した。¶
Internet Security Glossary [RFC4949] は、nonce について、 プロトコルによって交換されるデータに含まれるランダムまたは非反復の値として、 有用な定義を提供している。通常、その目的はライブネスを保証し、 それによってリプレイ攻撃を検出および防止することである。¶
しかし、[OpenID.Core]
による nonce クレームの初期登録では、
そのアプリケーションに文脈上固有の言葉が使用されており、
一般的な適用性を制限する可能性があった。¶
したがって、IANA は、"JSON Web Token Claims" レジストリ
[IANA.JWT] における
nonce の項目を、
そのクレームが他のコンテキストでも適切に使用できることを反映する拡張定義と、
参照としてこの文書を追加する形で、以下のように更新した。¶
IANA は、この文書で規定される以下の HTTP ヘッダーフィールドを、 [RFC9110] によって確立された "Hypertext Transfer Protocol (HTTP) Field Name Registry" [IANA.HTTP.Fields] に登録した。¶
IANA は、[RFC7591] によって 確立された IANA "OAuth Dynamic Client Registration Metadata" レジストリ [IANA.OAuth.Params] に、 以下の値を登録した。¶
この作業に対する貴重な意見、フィードバック、および全般的な支援について、 Brock Allen, Annabelle Backman, Dominick Baier, Spencer Balogh, Vittorio Bertocci, Jeff Corrigan, Domingos Creado, Philippe De Ryck, Andrii Deinega, William Denniss, Vladimir Dzhuvinov, Mike Engan, Nikos Fotiou, Mark Haine, Dick Hardt, Joseph Heenan, Bjorn Hjelm, Jacob Ideskog, Jared Jennings, Benjamin Kaduk, Pieter Kasselman, Neil Madden, Rohan Mahy, Karsten Meyer zu Selhausen, Nicolas Mora, Steinar Noem, Mark Nottingham, Rob Otto, Aaron Parecki, Michael Peck, Roberto Polli, Paul Querna, Justin Richer, Joseph Salowey, Rifaat Shekh-Yusef, Filip Skokan, Dmitry Telegin, Dave Tonge, Jim Willeke, およびその他の方々に感謝する。¶
この文書は、ドイツのシュトゥットガルトで開催された第4回 OAuth Security Workshop での議論に由来する。 このワークショップの主催者(Ralf Küsters および Guido Schmitz)に感謝する。¶