RFC 9700 OAuth 2.0セキュリティBCP 2025年1月
Lodderstedtほか ベストカレントプラクティス [ページ]
ストリーム:
Internet Engineering Task Force (IETF)
RFC:
9700
BCP:
240
更新対象:
6749, 6750, 6819
カテゴリ:
ベストカレントプラクティス
公開:
ISSN:
2070-1721
著者:
T. Lodderstedt
SPRIND
J. Bradley
Yubico
A. Labunets
独立研究者
D. Fett
Authlete

RFC 9700

OAuth 2.0セキュリティのベストカレントプラクティス

要旨

本文書は、OAuth 2.0のセキュリティに関するベストカレントプラクティスを記述する。これは、 RFC 6749、6750、および6819で示された脅威モデルとセキュリティ上の助言を更新し、拡張して、 OAuth 2.0の公開以降に蓄積された実践的な経験を取り入れ、OAuth 2.0のより広範な 適用によって関連するようになった新たな脅威を扱う。さらに、本書は、 安全性が低い、または安全でないと見なされる一部の運用モードを非推奨とする。

本文書の位置付け

このメモは、インターネットのベストカレントプラクティスを文書化するものである。

本文書は、Internet Engineering Task Force (IETF)の成果物である。これはIETFコミュニティの合意を表すものである。本文書は 公開レビューを受け、 Internet Engineering Steering Group (IESG)により公開が承認されている。BCPに関する詳細情報は RFC 7841のセクション2で入手できる。

本文書の現在の状態、あらゆる 正誤表、および本文書へのフィードバックの提供方法に関する情報は、 https://www.rfc-editor.org/info/rfc9700で入手できる。

目次

1. はじめに

[RFC6749] および[RFC6750]で公開されて以来、 OAuth 2.0(本文書では単に "OAuth" と呼ぶ)は市場で大きく普及し、API保護の標準となり、 OpenID Connect [OpenID.Core]を用いた フェデレーテッドログインの基盤となった。 OAuthはさまざまなシナリオおよび異なる種類のデプロイメントで使用されているが、 次のような課題が観察される。

本文書は、これらの課題に対処するための更新されたセキュリティ推奨事項を提供する。 OAuth 2.0 [RFC6749]や OpenID Connect [OpenID.Core] などの既存仕様で定義されたものを超える新たな要件を導入し、 安全性が低い、または安全でないと見なされる一部の運用モードを非推奨とする。 ただし、本文書は [RFC6749][RFC6750]、および[RFC6819]で示されたセキュリティ上の助言に取って代わるものではなく、 それらの文書を補完するものである。

当然ながら、既存のすべてのエコシステムや実装が 新しい要件と互換性を持つわけではなく、本文書で説明されるベストプラクティスに従うことで 相互運用性が損なわれる可能性がある。それでもなお、実装者が 可能な限り速やかに実装およびエコシステムをアップグレードすることが RECOMMENDEDである。

[OAUTH-V2.1]として開発中のOAuth 2.1は、 本文書のセキュリティ推奨事項を取り込む予定である。

1.1. 構成

本文書の残りは次のように構成されている。Section 2では、 すべてのOAuth実装者にとって最も重要なベストプラクティスを要約する。 Section 3では、更新されたOAuth攻撃者 モデルを提示する。Section 4では、 (執筆時点で)実際に見られる脅威および実装上の問題について詳細に分析し、 潜在的な対策について論じる。

1.2. 表記規約および 用語

本文書におけるキーワード「MUST」、 「MUST NOT」、 「REQUIRED」、「SHALL」、 「SHALL NOT」、 「SHOULD」、「SHOULD NOT」、 「RECOMMENDED」、「NOT RECOMMENDED」、 「MAY」、および「OPTIONAL」は、 ここに示すようにすべて大文字で現れる場合に限り、 BCP 14 [RFC2119] [RFC8174]で説明されるとおりに解釈される。

本仕様は、OAuth 2.0 [RFC6749]で定義される 「access token」、「authorization endpoint」、「authorization grant」、「authorization server」、「client」、 「client identifier」(client ID)、「protected resource」、「refresh token」、「resource owner」、「resource server」、および「token endpoint」という用語を使用する。

「open redirector」とは、クエリパラメーターから取得した任意のURIへ ユーザーのブラウザーを転送するWebサーバー上のエンドポイントである。

2. ベストプラクティス

本セクションでは、執筆時点でベストプラクティスと見なされる セキュリティ機構および対策の中核的な集合を説明する。 これらのセキュリティ機構および対策に関する詳細(詳細な攻撃の説明を含む)、 ならびにあまり一般的に使用されない選択肢に対する要件は、 Section 4で提供される。

2.1. リダイレクトベースのフローの保護

事前登録されたURIとクライアントリダイレクトURIを比較する際、 認可 サーバーは、ネイティブアプリのlocalhostリダイレクトURIにおける ポート番号を除き、厳密な文字列照合を利用 MUSTである(Section 4.1.3を参照)。この 対策は、認可コードおよび アクセストークンの漏えい防止に寄与する(Section 4.1を参照)。また、 Mix-Up攻撃の検出にも役立つ可能性がある(Section 4.4を参照)。

クライアントおよび認可サーバーは、 Section 4.11で説明されるような、 クエリパラメーターから取得した任意のURIへユーザーのブラウザーを転送するURL (オープンリダイレクター)を公開しては MUST NOTならない。オープンリダイレクターは、 認可コードおよびアクセストークンの流出を可能にすることがある。

クライアントはCross-Site Request Forgery (CSRF)を防止 MUSTである。この 文脈において、CSRFとは、認可サーバーではなく悪意ある第三者から発生する、 リダイレクトエンドポイントへのリクエストを指す(詳細については Section 4.4.1.8 of [RFC6819]を参照)。 認可サーバーがProof Key for Code Exchange (PKCE) [RFC7636]をサポートすることを 確認済みのクライアントは、PKCEによって提供されるCSRF保護に依存 MAYできる。OpenID Connectフローでは、 nonceパラメーターがCSRF保護を提供する。それ以外の場合、ユーザーエージェントに 安全に結び付けられた、stateパラメーターで運ばれる一回限り使用の CSRFトークンをCSRF保護に使用 MUSTである(Section 4.7.1を参照)。

OAuthクライアントが複数の認可サーバーとやり取りできる場合、 Mix-Up攻撃(Section 4.4を参照)に対する防御がREQUIREDである。そのために、クライアントは SHOULD

  • [RFC9207]に従った対策として issパラメーターを使用する、または
  • 認可レスポンス内の iss値([OpenID.Core]におけるID Token内の issクレーム、または[OpenID.JARM]レスポンス内のものなど)に基づく 代替対策を使用し、 その値を[RFC9207]で説明されるとおりに処理する。

これらの選択肢がない場合、クライアントは代わりに、 Section 4.4.2で説明されるように、 認可エンドポイントおよびトークンエンドポイントを識別するために個別のリダイレクトURIを使用 MAYできる。

ユーザークレデンシャルを含む可能性があるリクエストをリダイレクトする認可サーバーは、 これらのユーザークレデンシャルを誤って転送することを回避 MUSTである(詳細については Section 4.12を参照)。

2.1.1. 認可 コードグラント

クライアントは、次のいずれかの選択肢を用いて、認可コード インジェクション攻撃(Section 4.5を参照)および認可コードの悪用を防止 MUSTである。

  • パブリッククライアントは、この目的のために PKCE [RFC7636]を使用 MUSTである。これは Section 4.5.3.1で動機付けられている。
  • コンフィデンシャルクライアントについては、PKCE [RFC7636]の使用が RECOMMENDEDである。これは、 Section 4.5.3.1で説明されるように、認可 コードの悪用および注入に対する強力な保護を提供するためである。また副次的効果として、 Section 4.7.1で説明される 強力な攻撃者が存在する場合でもCSRFを防止する。
  • Section 4.5.3.2で説明される追加の予防措置を講じたうえで、 コンフィデンシャルOpenID Connect [OpenID.Core]クライアントは、代わりに nonceパラメーターおよびID Token内の対応するClaimを使用 MAYできる。

いずれの場合も、PKCEチャレンジまたはOpenID Connect nonceは、 トランザクション固有であり、 そのトランザクションが開始されたクライアントおよびユーザーエージェントに安全に結び付けられて MUSTいる。 認可サーバーは、PKCEチャレンジまたはOpenID Connect nonceに定数値が使用されることを検出し、防止するために合理的な努力を行うことが推奨される。

注: PKCEはネイティブ アプリを保護する仕組みとして設計されたが、この助言はWeb アプリケーションを含むあらゆる種類のOAuthクライアントに適用される。

PKCEを使用する場合、クライアントは、 認可リクエスト内でPKCE verifierを露出しないPKCE code challenge methodを使用 SHOULDである。 そうでない場合、認可リクエストを読み取ることができる攻撃者(Section 3のAttacker (A4)を参照)は、PKCEによって提供されるセキュリティを破ることができる。 現在、S256が唯一のそのような方法である。

認可サーバーはPKCE [RFC7636]をサポート MUSTである。

クライアントが認可リクエスト内で有効なPKCE code_challengeパラメーターを送信した場合、認可サーバーは、 トークンエンドポイントでのcode_verifierの正しい使用を強制 MUSTである。

認可サーバーは、 code_verifierパラメーターを含むトークンリクエストが、 認可リクエスト内にcode_challengeパラメーターが存在していた場合にのみ 受け入れられることを保証することで、PKCEダウングレード攻撃を緩和 MUSTである。詳細については Section 4.8.2 を参照。

認可サーバーは、 PKCEのサポートを検出する方法を提供 MUSTである。認可サーバーは、 Authorization Server Metadata [RFC8414]内に、 サポートされるPKCEチャレンジ方式を含む code_challenge_methods_supported要素(クライアントがPKCEサポートを検出するために使用できる)を 公開することが RECOMMENDEDである。認可サーバーは、代わりに、 認可サーバーによるPKCEサポートを保証または判定するためのデプロイメント固有の方法を提供 MAYできる。

2.1.2. インプリシットグラント

インプリシットグラント(レスポンスタイプtoken)および、 認可サーバーが認可レスポンス内でアクセストークンを発行することを引き起こす その他のレスポンスタイプは、 Sections 4.14.24.3、および 4.6で説明されるように、 アクセストークン漏えいおよび アクセストークンリプレイに対して脆弱である。

さらに、アクセストークンが 認可レスポンス内で発行される場合、(Section 2.2で 推奨されるように)アクセストークンを特定のクライアントに結び付けるための 送信者制約を行う標準化された方法は存在しない。 これは、攻撃者が漏えいまたは盗難されたアクセストークンをリソースエンドポイントで使用できることを意味する。

これらの問題を避けるため、クライアントは、 認可レスポンス内でのアクセストークン注入が防止され、前述のトークン漏えい ベクトルが緩和されていない限り、インプリシット グラント(レスポンスタイプtoken)または認可レスポンス内で アクセストークンを発行するその他のレスポンスタイプを使用すべきでは SHOULD NOTない。

クライアントは代わりに、 Section 2.1.1で規定されるレスポンス タイプcode(すなわち、認可 コードグラントタイプ)、またはcode id_tokenレスポンスタイプのように 認可サーバーがトークンレスポンス内でアクセストークンを発行することを引き起こす その他のレスポンスタイプを使用 SHOULDである。これにより、 認可サーバーは攻撃者によるリプレイ試行を検出でき、 アクセストークンがURLに露出しないため、一般に攻撃対象領域が削減される。 また、認可サーバーが発行されたトークンに 送信者制約を付けることも可能になる(Section 2.2を参照)。

2.2. トークンリプレイ 防止

2.2.1. アクセストークン

送信者制約付きアクセストークンは、 アクセス トークンの適用範囲を特定の送信者に限定する。この送信者は、 そのトークンが受信者(たとえばリソースサーバー)で受け入れられる前提条件として、 特定の秘密を知っていることを示す義務を負う。

認可サーバーおよびリソースサーバーは、 盗まれた、または漏えいしたアクセストークンの悪用を防止するために、 OAuth 2.0の相互TLS [RFC8705]またはOAuth 2.0 Demonstrating Proof of Possession (DPoP) [RFC9449]Section 4.10.1を参照) など、アクセストークンに送信者制約を付ける仕組みを使用 SHOULDである。

2.2.2. リフレッシュトークン

パブリッククライアント向けのリフレッシュトークンは、 送信者制約付きであるか、Section 4.14で説明されるリフレッシュ トークンローテーションを使用 MUSTである。[RFC6749]はすでに、 コンフィデンシャルクライアント向けのリフレッシュトークンは、それが発行された クライアントによってのみ使用できることを義務付けている。

2.3. アクセストークン権限 制限

アクセストークンに関連付けられる権限は、 特定のアプリケーションまたはユースケースに必要な最小限に制限 SHOULDされる。これにより、 クライアントがリソース所有者によって認可された権限を超えることを防ぐ。 また、ユーザーがそれぞれのセキュリティポリシーによって認可された権限を 超えることも防ぐ。権限制限は、 アクセストークン漏えいの影響を低減するのにも役立つ。

特に、アクセストークンは、 特定のリソースサーバー、またはそれが実現できない場合には少数のリソースサーバーに対して オーディエンス制限 SHOULDされる。これを実施するために、 認可サーバーはアクセストークンを特定のリソースサーバーに関連付け、 各リソースサーバーは、すべてのリクエストについて、そのリクエストとともに送信された アクセストークンが当該リソースサーバーで使用されることを意図したものかどうかを検証する義務を負う。 意図されたものでない場合、リソースサーバーは当該リクエストの処理を拒否 MUSTである。 [RFC9068]で定義されるaudクレームは、 アクセストークンをオーディエンス制限するために使用 MAYできる。クライアントおよび認可サーバーは、 アクセスしたいリソースサーバーを決定するために、それぞれ[RFC6749]および [RFC8707]で規定される scopeまたはresourceパラメーターを利用 MAYできる。

さらに、アクセストークンは、 リソースサーバー上の特定のリソースおよびアクション、またはリソースに制限 SHOULDされる。これを実施するために、 認可サーバーはアクセストークンを対応するリソースおよびアクションに関連付け、 各リソースサーバーは、すべてのリクエストについて、そのリクエストとともに送信された アクセストークンが当該リソースに対する当該アクションに使用されることを 意図したものかどうかを検証する義務を負う。 意図されたものでない場合、リソースサーバーは当該リクエストの処理を拒否しなければならない。 クライアントおよび認可サーバーは、 これらのリソースおよび/またはアクションを決定するために、 [RFC6749]で規定される scopeパラメーターおよび[RFC9396]で 規定されるauthorization_detailsを利用 MAYできる。

2.4. リソース所有者 パスワードクレデンシャルグラント

リソース所有者パスワードクレデンシャルグラント [RFC6749]は使用しては MUST NOTならない。このグラントタイプは、リソース 所有者のクレデンシャルをクライアントに安全でない形で露出する。 クライアントが善意であっても、このグラントを使用すると攻撃対象領域が増加し (すなわち、クレデンシャルが認可サーバー以外の場所でも漏えいする可能性がある)、 ユーザーに対して認可サーバー以外の場所にクレデンシャルを入力する習慣を身につけさせることになる。

さらに、リソース所有者パスワードクレデンシャルグラントは、 二要素認証や、複数のユーザー操作ステップを必要とする認証プロセスと連携するようには設計されていない。 暗号クレデンシャルによる認証 (WebCrypto [W3C.WebCrypto]、 WebAuthn [W3C.WebAuthn]を参照)は、 通常は特定のWebオリジンに結び付けられているため、このグラントタイプで実装することは 不可能な場合がある。

2.5. クライアント認証

認可サーバーは、特定のデプロイメントにおいて、 クライアント向けのクレデンシャルの発行/登録プロセスを確立し、 それらのクレデンシャルの機密性を保証することが可能である場合、 クライアント認証を強制 SHOULDである。

クライアント認証には、OAuth 2.0の相互TLS [RFC8705]や、 [RFC7521]および [RFC7523]に従った署名付きJWT ("Private Key JWT")など、非対称暗号を使用することが RECOMMENDEDである。後者は [OpenID.Core]において クライアント認証方式private_key_jwtとして定義されている。 クライアント認証に非対称暗号を使用する場合、認可 サーバーは機密性の高い対称鍵を保存する必要がないため、 これらの方式は鍵の漏えいに対してより堅牢になる。

2.6. その他の推奨事項

OAuth Authorization Server Metadata [RFC8414]の使用は、 OAuthデプロイメントのセキュリティ向上に役立つ。

  • これにより、準拠するソフトウェアライブラリによって セキュリティ機能およびその他の新しいOAuth機能を自動的に有効化できる。
  • 設定ミスの可能性を低減する。たとえば、 設定ミスのあるエンドポイントURL(攻撃者に属する可能性があるもの)や、 設定ミスのあるセキュリティ機能などである。
  • 暗号鍵のローテーションを促進し、 暗号アジリティを確保するのに役立つ。

したがって、認可 サーバーが[RFC8414]に従って OAuth Authorization Server Metadataを公開し、クライアントが (利用可能な場合)このAuthorization Server Metadataを使用して自身を設定することが RECOMMENDEDである。

Section 4.15.1で 説明される条件の下では、認可サーバーは、クライアントが自身の client_idまたは 本物のリソース所有者との混同を引き起こし得るその他のクレームに影響を与えることを許可すべきでは SHOULD NOTない。

クライアントと リソースサーバーの間では、[BCP195]に従った エンドツーエンドTLSを使用することが RECOMMENDEDである。TLS トラフィックを中間者で終端する必要がある場合は、 追加のセキュリティ助言について Section 4.13を参照。

認可レスポンスは、暗号化されていないネットワーク 接続上で送信しては MUST NOTならない。この目的のため、認可サーバーは、 Section 7.3 of [RFC8252]で説明されるループバックインターフェイスリダイレクトを使用する ネイティブクライアントを除き、http スキームを使用するリダイレクトURIを許可しては MUST NOTならない。

認可レスポンスがHTTPリダイレクトの代わりに postMessage [WHATWG.postmessage_api]のようなブラウザー内通信技術によって送信される場合、 ブラウザー内メッセージの開始側と受信側の両方は、 Section 4.17で説明されるように厳密に検証されて MUSTならない。

ブラウザーベースのクライアントをサポートするために、 Token Endpoint、Authorization Server Metadata Endpoint、jwks_uri Endpoint、およびDynamic Client Registration Endpointを含む、そのようなクライアントから直接アクセスされるエンドポイントは、 Cross-Origin Resource Sharing (CORS) [WHATWG.CORS]の使用をサポート MAYできる。 ただし、CORSは認可エンドポイントではサポートしては MUST NOTならない。クライアントはこのエンドポイントに直接アクセスせず、 代わりにユーザーエージェントをそこへリダイレクトするためである。

3. 更新されたOAuth 2.0攻撃者モデル

[RFC6819]では、 OAuthデプロイメントが保護されなければならない脅威を記述する脅威モデルが示されている。 その際、[RFC6819]は、攻撃者とその能力について一定の仮定を置いている。 すなわち、暗黙のうちに攻撃者モデルを確立している。以下では、この攻撃者モデルを 明示し、(Section 1で説明したような)複数の当事者を含む潜在的に動的な 関係を考慮し、新しい種類の攻撃者を含め、攻撃者モデルをより明確に定義するために、 更新および拡張する。

本文書の目的は、認可サーバーにおけるリソース所有者 (ユーザーエージェントを伴う)の認可と、その後のリソースサーバーにおける アクセストークンの使用が、少なくとも次の攻撃者に対して、 実用上可能な限り保護されることを保証することである。

(A1)

ブラウザーやサーバーを含む任意の数の ネットワークエンドポイント(「正直な」ものを除く)を設定し運用できる Web攻撃者。Web攻撃者は、リソース所有者が訪問するWebサイトを設定し、 自身のユーザーエージェントを運用し、プロトコルに参加することができる。

特に、Web攻撃者は、認可サーバーに登録された OAuthクライアントを運用でき、また、リソース所有者や他のリソース所有者が (「正直な」ものと並行して)使用できる、自身の認可サーバーおよび リソースサーバーを運用できる。

また、Web攻撃者は任意の時点で、攻撃者が選んだ任意のURIへ ユーザーのブラウザーを誘導できると仮定しなければならない。実際には、これは 広告ネットワークに悪意ある広告を注入する、正当らしく見えるメールを送信するなど、 多くの方法で実現できる。

Web攻撃者は、自身のユーザークレデンシャルおよび 以前に知り得た任意の秘密を使用して、新しいメッセージを作成できる。 たとえば、Web攻撃者が設定ミスのあるリダイレクトURIを通じて ユーザーの認可コードを知った場合、そのWeb攻撃者はそのコードを アクセストークンと交換しようとすることができる。

しかし、攻撃者を対象としていないメッセージ (たとえば、攻撃者の制御下にない認可サーバーのURLへ送信されたもの)を 読み取ったり操作したりすることはできない。

(A2)

さらに、プロトコル参加者が通信するネットワークを 完全に制御できるネットワーク攻撃者。これらの攻撃者は、 メッセージが暗号方式(たとえばTLS)によって適切に保護されている場合を除き、 メッセージを盗聴、操作、および偽装できる。 ネットワーク攻撃者は任意のメッセージをブロックすることもできる。

Web攻撃者の例としてはインターネットサービスプロバイダーの顧客が考えられ、 ネットワーク攻撃者としては、インターネットサービスプロバイダー自体、 ARPスプーフィングを用いる公共(Wi-Fi)ネットワーク上の攻撃者、または インターネットエクスチェンジポイントへアクセスできる国家支援攻撃者などが考えられる。

前述の攻撃者(A1)および (A2)は、OAuthの形式的解析 [arXiv.1601.01229]で使用された攻撃者モデルに適合する。 これは最小限の攻撃者モデルである。 実装者は、自身のOAuth実装の環境において考えられるすべての種類の攻撃者を考慮 MUSTしなければならない。たとえば、[arXiv.1901.11520]では、 トークンエンドポイントを完全に制御する攻撃者を含む、非常に強力な攻撃者モデルが使用されている。 これは、エコシステム内のエンドポイント設定ミスの影響をモデル化しているが、 Section 2.6で説明した認可サーバーメタデータを使用することで回避できる。 したがって、このような攻撃者はここには列挙していない。

しかし、OAuthに対する過去の攻撃は、次の種類の攻撃者が 特に関連することを示している。

(A3)

認可レスポンスの内容を読み取ることはできるが、変更することはできない攻撃者 (すなわち、認可レスポンスが攻撃者に漏えいする可能性がある)。

このような攻撃の例には、オープンリダイレクター攻撃や Mix-Up攻撃(Section 4.4を参照)が含まれる。 これらでは、クライアントが攻撃者の制御する認可サーバーへ クレデンシャルを送信するようにだまされる。

また、次のものを悪用する攻撃も含まれる。

  • リダイレクトURIの不十分な検査(Section 4.1を参照)。
  • 異なるアプリが同じURIへ自身を登録できる モバイルオペレーティングシステム上に存在する問題。および
  • ブラウザー(履歴)、プロキシサーバー、および オペレーティングシステムによって保存/ログ記録されるURL。
(A4)

認可リクエストの内容を読み取ることはできるが、 変更することはできない攻撃者(すなわち、認可リクエストが上記と同様の方法で 攻撃者に漏えいする可能性がある)。

(A5)

認可サーバーによって発行されたアクセストークンを取得できる攻撃者。 たとえば、リソースサーバーが攻撃者に侵害される、設定ミスにより アクセストークンが攻撃者の制御するリソースサーバーへ送信される、または ソーシャルエンジニアリングによってリソース所有者に攻撃者の制御する リソースサーバーを使用させることがあり得る。Section 4.9.2も参照。

(A3)(A4)、および(A5)は、 通常、(A1)または(A2)のいずれかと共に発生する。 攻撃者は共通の目標に到達するために協力できる。

攻撃者(A1)または(A2)は、リソース所有者であることも、 リソース所有者として振る舞うこともできる点に注意すること。たとえば、そのような攻撃者は、 自身のブラウザーを使用して、上記のいずれかの攻撃で取得したトークンまたは認可コードを クライアントまたはリソースサーバーでリプレイできる。

本文書は、攻撃者(A1)から(A5)までに起因する脅威に焦点を当てる。

4. 攻撃と緩和策

本セクションでは、OAuth実装に対する攻撃について、 潜在的な対策とともに詳細に説明する。[RFC6819]で すでに扱われている攻撃および緩和策は、新しい推奨事項が示される場合を除き、ここには列挙しない。

本セクションではさらに、特定のケースおよびプロトコルオプションについて、 (Section 2で定義されたものを超える) 追加要件を定義する。

4.1. 不十分な リダイレクトURI検証

一部の認可サーバーは、完全なリダイレクトURIの代わりに、 クライアントがリダイレクトURIパターンを登録することを許可している。 認可サーバーはその後、実行時に認可エンドポイントでリダイレクトURIパラメーター値を 登録済みパターンと照合する。このアプローチにより、クライアントは トランザクション状態を追加のリダイレクトURIパラメーターにエンコードしたり、 複数のリダイレクトURIのために単一のパターンを登録したりできる。

このアプローチは、厳密なリダイレクトURI照合よりも 実装が複雑で、管理時に誤りを起こしやすいことが判明した。 パターン照合実装または具体的な設定の欠陥を悪用する成功した攻撃が、 実際に複数観察されている(たとえば[research.rub2]を参照)。 リダイレクトURIの不十分な検証は、(グラントおよびクライアント種別に応じて) クライアント識別または認証を事実上破壊し、攻撃者が認可コードまたは アクセストークンを取得することを可能にする。それは次のいずれかによる。

  • ユーザーエージェントを攻撃者の制御下にあるURIへ 直接送信することによる、または
  • ユーザーエージェントがURLフラグメントを扱う方法と組み合わせて、 クライアントにあるオープンリダイレクターを利用し、OAuthクレデンシャルを 攻撃者へ露出させることによる。

これらの攻撃は、以下のサブセクションで詳細に示す。

4.1.1. 認可コードグラントに対する リダイレクトURI検証攻撃

グラントタイプcodeを使用するクライアントに対しては、 攻撃は次のように機能する可能性がある。

リダイレクトURLパターン https://*.somesite.example/*が、クライアントID s6BhdRkqt3を持つクライアントに登録されていると仮定する。 その意図は、somesite.exampleの任意のサブドメインを、 たとえばhttps://app1.somesite.example/redirectのように、 そのクライアントの有効なリダイレクトURIとして許可することである。 しかし、認可サーバー上の素朴な実装は、ワイルドカード*を 「ドメイン名として有効な任意の文字」ではなく「任意の文字」と解釈する可能性がある。 したがって、認可サーバーは、attacker.exampleが悪意ある当事者によって 制御される可能性のある異なるドメインであるにもかかわらず、 https://attacker.example/.somesite.exampleをリダイレクトURIとして 許可してしまう可能性がある。

攻撃は次のように実行できる。

まず、攻撃者は、攻撃者の制御下にあるページ、 たとえばhttps://www.evil.exampleを起動する改ざんされたURLを ユーザーがブラウザーで開くようにだます必要がある(Section 3の攻撃者A1を参照)。

このURLは、正当なクライアントのクライアントIDを用いて、 認可エンドポイントに対する次の認可リクエストを開始する(改行は表示のためのみ)。

GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=9ad67f13
     &redirect_uri=https%3A%2F%2Fattacker.example%2F.somesite.example
     HTTP/1.1
Host: server.somesite.example

認可サーバーはリダイレクトURIを検証し、 クライアントs6BhdRkqt3に登録されたリダイレクトURLパターンと比較する。 認可リクエストは処理され、ユーザーに提示される。

ユーザーがリダイレクトURIを見ない、または攻撃を認識しない場合、 コードが発行され、直ちに攻撃者のドメインへ送信される。 認可の自動承認が有効になっている場合(これは[RFC6749]によればパブリッククライアントには推奨されない)、 この攻撃はユーザー操作なしでも実行できる。

攻撃者がパブリッククライアントになりすます場合、 攻撃者は対応するトークンエンドポイントでコードをトークンと交換できる。

この攻撃は、コード交換に正当なクライアントの秘密による認証が 必要であるため、コンフィデンシャルクライアントに対してはそれほど容易には機能しない。 しかし、攻撃者は、認可コードインジェクション攻撃を実行することで、 正当なコンフィデンシャルクライアントにコードを引き換えさせることができる。 Section 4.5を参照。

認可サーバーがワイルドカードを適切に処理している場合でも、 リダイレクトURI検証の脆弱性が存在し得る点に注意することが重要である。 たとえば、クライアントがリダイレクトURLパターン https://*.somesite.example/*を登録し、認可サーバーがこれを 「ドメインsomesite.example内に存在する任意のホストを指すリダイレクトURIを許可する」 と解釈すると仮定する。攻撃者がsomesite.example内にホストまたは サブドメインを確立できた場合、攻撃者は正当なクライアントになりすますことができる。 たとえば、これはサブドメイン乗っ取り攻撃[research.udel]によって引き起こされ得る。 その場合、古いCNAMEレコード(たとえばexternal-service.somesite.example)が、 もはや存在しない外部DNS名(たとえばcustomer-abc.service.example)を指しており、 攻撃者が(たとえば外部サービスにcustomer-abcとして登録することで) それを乗っ取れる可能性がある。

4.1.2. インプリシットグラントに対する リダイレクトURI検証攻撃

上記の攻撃はインプリシットグラントでも機能する。 攻撃者が認可レスポンスを攻撃者の制御するURIへ送信できる場合、 攻撃者はアクセストークンを含むフラグメントに直接アクセスできる。

さらに、インプリシットグラント(および[OAuth.Responses]で定義される response_mode=fragmentを使用する場合の他のグラント)には、 さらに別の種類の攻撃が生じる可能性がある。この攻撃は、 Locationヘッダーにフラグメントが含まれていない場合、ユーザーエージェントが リダイレクト先URLへフラグメントを再付加するという事実を利用する (Section 17.11 of [RFC9110]を参照)。ここで説明する攻撃は、 アクセストークンを取得するために、この挙動とオープンリダイレクターとしての クライアント(Section 4.11.1を参照)を組み合わせる。これにより、非常に狭いリダイレクトURIパターンでさえ 回避できるが、厳密なURL照合は回避できない。

クライアントs6BhdRkqt3に登録されたURLパターンが https://client.somesite.example/cb?*である、すなわち https://client.somesite.example/cbへのリダイレクトについて任意の パラメーターが許可されていると仮定する。残念ながら、クライアントはオープンリダイレクターを公開している。 このエンドポイントは、ターゲットURLを受け取り、HTTP Locationヘッダーによる303リダイレクトを使って ブラウザーをそのURLへ送信するredirect_toパラメーターをサポートしている。

攻撃は次のように実行できる。

まず、上記と同様に、攻撃者は、攻撃者の制御下にあるページ、 たとえばhttps://www.evil.exampleを起動する改ざんされたURLを ユーザーがブラウザーで開くようにだます必要がある。

その後、Webサイトはコードフローに対する攻撃のものと非常によく似た 認可リクエストを開始する。上記と異なり、 redirect_to=https://attacker.exampleをリダイレクトURIのパラメーターに エンコードすることでオープンリダイレクターを利用し、レスポンスタイプtokenを使用する (改行は表示のためのみ)。

GET /authorize?response_type=token&state=9ad67f13
    &client_id=s6BhdRkqt3
    &redirect_uri=https%3A%2F%2Fclient.somesite.example
     %2Fcb%26redirect_to%253Dhttps%253A%252F
     %252Fattacker.example%252F HTTP/1.1
Host: server.somesite.example

すると、リダイレクトURIが登録済みパターンと一致するため、 認可サーバーはリクエストを許可し、結果のアクセストークンを303リダイレクトで送信する (一部のレスポンスパラメーターは読みやすさのため省略)。

HTTP/1.1 303 See Other
Location: https://client.somesite.example/cb?
          redirect_to%3Dhttps%3A%2F%2Fattacker.example%2Fcb
          #access_token=2YotnFZFEjr1zCsicMWpAA&...

client.somesite.exampleでは、リクエストはオープンリダイレクターに到達する。 エンドポイントはredirectパラメーターを読み取り、URL https://attacker.example/へのHTTP 303 Locationヘッダーリダイレクトを発行する。

HTTP/1.1 303 See Other
Location: https://attacker.example/

client.somesite.exampleのリダイレクターは Locationヘッダーにフラグメントを含めないため、ユーザーエージェントは元のフラグメント #access_token=2YotnFZFEjr1zCsicMWpAA&...をURLへ再付加し、 次のURLへ移動する。

https://attacker.example/#access_token=2YotnFZFEjr1z...

その後、attacker.exampleの攻撃者のページは フラグメントにアクセスし、アクセストークンを取得できる。

4.1.3. 対策

パターン照合を正しく実装および管理する複雑さは、 明らかにセキュリティ問題を引き起こす。したがって、本文書は、 厳密なリダイレクトURI照合を使用することで、必要なロジックおよび設定を 単純化することを助言する。これは、認可サーバーが2つのURIが等しいことを保証 MUSTしなければならないことを意味する。 詳細については、Section 6.2.1 of [RFC3986]のSimple String Comparisonを参照。 唯一の例外は、localhost URIを使用するネイティブアプリである。この場合、 認可サーバーはSection 7.3 of [RFC8252]で説明されるように、 可変ポート番号を許可 MUSTしなければならない。

追加の推奨事項。

  • リダイレクトURIがホストされるWebサーバーは、 オープンリダイレクターを公開しては MUST NOTならない(Section 4.11を参照)。
  • ブラウザーは、Locationヘッダー内のURLが すでにフラグメントを含んでいない場合に限り、URLフラグメントをLocationリダイレクトURLへ 再付加する。したがって、サーバーは、Locationヘッダー内のURLへ任意のフラグメント識別子、 たとえば#_を付加することで、ブラウザーがフラグメントを リダイレクトURLへ再付加することを防止 MAYできる。
  • クライアントは、認可エンドポイントで アクセストークン発行を引き起こすレスポンスタイプではなく、認可コードレスポンスタイプを使用 SHOULDする。これにより、認可サーバーとの交換プロセスを通じた 漏えいクレデンシャルの再利用に対する対策、およびアクセストークンの 送信者制約によるトークンリプレイに対する対策が提供される。

リダイレクトURIを含む認可リクエストの起源および完全性を検証できる場合、 たとえばクライアント認証とともに [RFC9101]または[RFC9126]を使用する場合、 認可サーバーは追加の検査なしにリダイレクトURIを信頼 MAYできる。

4.2. Refererヘッダーを介した クレデンシャル漏えい

認可リクエストURIまたは認可レスポンスURIの内容は、 それぞれ認可サーバーまたはクライアントのWebサイトから漏れることにより、 Referer HTTPヘッダー(Section 10.1.3 of [RFC9110]を参照)を通じて、意図せず攻撃者に開示される可能性がある。 最も重要な点として、認可コードまたはstate値がこの方法で開示され得る。 Section 10.1.3 of [RFC9110]では別途規定されているものの、 Chromiumプロジェクトの(現在は修正済みの)問題 [bug.chromium]で例示されるように、 ブラウザー実装の問題により、URIフラグメントで運ばれるアクセストークンにも同じことが起こり得る。

4.2.1. OAuthクライアントからの 漏えい

OAuthクライアントからの漏えいは、成功した認可リクエストの結果として、 クライアントが次のようなページをレンダリングすることを必要とする。

  • 攻撃者の制御下にある他のページへのリンクを含み、 ユーザーがそのようなリンクをクリックする、または
  • サードパーティコンテンツ (iframe内の広告、画像など)を含む。たとえば、そのページに ユーザー生成コンテンツ(ブログ)が含まれる場合である。

ブラウザーが攻撃者のページへ移動する、またはサードパーティコンテンツを読み込むとすぐに、 攻撃者は認可レスポンスURLを受け取り、codeまたはstate (場合によってはaccess_token)を抽出できる。

4.2.2. 認可サーバーからの 漏えい

同様の方法で、認可サーバーの認可エンドポイントに 上記のようなリンクまたはサードパーティコンテンツが含まれる場合、 攻撃者は認可リクエストからstateを知ることができる。

4.2.3. 影響

Refererヘッダーを通じて有効なコードまたはアクセストークンを知った攻撃者は、 Sections 4.1.14.5、および 4.6で説明される攻撃を実行できる。 攻撃者がstateを知った場合、stateを使用して得られるCSRF保護は失われ、 Section 4.4.1.8 of [RFC6819]で説明される CSRF攻撃につながる。

4.2.4. 対策

OAuth認可レスポンスの結果としてレンダリングされるページおよび 認可エンドポイントは、サードパーティリソースまたは外部サイトへのリンクを含めるべきでは SHOULD NOTない。

次の対策は、攻撃が成功する可能性をさらに低減する。

  • 適切なReferrer Policy [W3C.webappsec-referrer-policy]を文書に適用する ("referrer" meta属性の一部として、またはReferrer-Policyヘッダーを設定することで) ことにより、Refererヘッダーを抑止する。たとえば、レスポンス内のヘッダー Referrer-Policy: no-referrerは、結果の文書から発生するすべてのリクエストにおいて Refererヘッダーを完全に抑止する。
  • 認可エンドポイントから アクセストークン発行を引き起こすレスポンスタイプではなく、認可コードを使用する。
  • 認可コードをコンフィデンシャルクライアントまたは PKCEチャレンジに結び付ける。この場合、攻撃者はコード交換を要求するための秘密を持たない。
  • Section 4.1.2 of [RFC6749]で説明されるように、 認可コードはトークンエンドポイントで最初に使用された後、認可サーバーによって無効化され MUSTる。たとえば、認可サーバーが正当なクライアントによる引き換え後に コードを無効化した場合、攻撃者は後でこのコードを交換できない。

    これは、攻撃者が正当なクライアントより先に コードをトークンと交換できた場合には攻撃を緩和しない。したがって、 [RFC6749]はさらに、 コードを二度引き換えようとする試みが行われた場合、認可サーバーは そのコードに基づいて以前に発行されたすべてのトークンを失効 SHOULDさせることを推奨している。

  • state値は、リダイレクトエンドポイントで 最初に使用された後にクライアントによって無効化される SHOULDである。これが実装されており、 攻撃者がクライアントのWebサイトからRefererヘッダーを通じてトークンを受け取った場合、 stateはすでに使用済みで、クライアントによって無効化されており、 攻撃者が再び使用することはできない。(これは、stateが 認可サーバーのWebサイトから漏れた場合には役に立たない。その場合、stateはまだ クライアントのリダイレクトエンドポイントで使用されていないためである。)

  • 認可レスポンスには、リダイレクトの代わりに form postレスポンスモードを使用する([OAuth.Post]を参照)。

4.3. ブラウザー履歴を介した クレデンシャル漏えい

認可コードおよびアクセストークンは、ブラウザーの 訪問済みURL履歴に残る可能性があり、以下で説明する攻撃を可能にする。

4.3.1. ブラウザー履歴内の 認可コード

プロバイダーの認可エンドポイントからのリダイレクトの結果として、 ブラウザーがclient.example/redirection_endpoint?code=abcdへ移動する場合、 認可コードを含むURLがブラウザー履歴に残る可能性がある。 デバイスへアクセスできる攻撃者は、コードを取得しリプレイを試みることができる。

対策。

  • Section 4.4.1.1 of [RFC6819]およびSection 4.5で説明される認可コードリプレイ防止。
  • 認可レスポンスには、リダイレクトの代わりに form postレスポンスモードを使用する([OAuth.Post]を参照)。

4.3.2. ブラウザー履歴内の アクセストークン

すでにトークンを持つクライアントまたはWebサイトが、 provider.com/get_user_profile?access_token=abcdefのようなページへ 意図的に移動する場合、アクセストークンがブラウザー履歴に残る可能性がある。 [RFC6750]はこの慣行を推奨せず、 トークンをヘッダー経由で転送するよう助言しているが、実際にはWebサイトが クエリパラメーターでアクセストークンを渡すことがよくある。

インプリシットグラントの場合、プロバイダーの 認可エンドポイントからのリダイレクトの結果として、 client.example/redirection_endpoint#access_token=abcdefのようなURLも ブラウザー履歴に残る可能性がある。

対策。

  • クライアントは、Section 2.3 of [RFC6750]で説明される方法で、 URIクエリパラメーターにアクセストークンを渡しては MUST NOTならない。 この目的のために、認可コードグラントまたはform postレスポンスモード [OAuth.Post]のような 代替OAuthレスポンスモードを使用できる。

4.4. Mix-Up攻撃

Mix-Up攻撃は、OAuthクライアントが2つ以上の認可サーバーとやり取りし、 少なくとも1つの認可サーバーが攻撃者の制御下にあるシナリオで発生し得る。 たとえば、攻撃者が動的登録を使用して自身の認可サーバーにクライアントを登録する場合、 または認可サーバーが侵害される場合がこれに該当する。

攻撃の目的は、侵害されていない認可サーバーに対する認可コードまたは アクセストークンを取得することである。これは、クライアントをだまして、 それらのクレデンシャルを、侵害されていない認可/リソースサーバーの 対応するエンドポイントで使用させる代わりに、侵害された認可サーバー (攻撃者)へ送信させることで達成される。

4.4.1. 攻撃の説明

ここでの説明は[arXiv.1601.01229]に従っており、 攻撃の変種を以下に概説する。

前提条件: この攻撃の変種が機能するには、次を仮定する。

  • インプリシットグラントまたは認可コードグラントが 複数の認可サーバーとともに使用され、そのうち1つが「正直な」もの(H-AS)、 もう1つが攻撃者によって運用されるもの(A-AS)であること。および
  • クライアントが、ユーザーによって選択された認可サーバーを ユーザーのブラウザーに結び付けられたセッションに保存し、 各認可サーバーに同じリダイレクトURIを使用すること。

以下ではさらに、クライアントがH-AS (URI: https://honest.as.example、クライアントID: 7ZGZldHQ)およびA-AS(URI: https://attacker.example、クライアントID: 666RVZJTA)に 登録されていると仮定する。以下の例で示すURLは、攻撃に関連するパラメーターのみを含むように 表示のため短縮されている。

認可コードグラントに対する攻撃。

  1. ユーザーは、A-ASを使用してグラントを開始することを選択する (たとえば、クライアントのWebサイト上のボタンをクリックする)。
  2. クライアントは、ユーザーが「A-AS」を選択したことを ユーザーのセッションに保存し、URL https://attacker.example/authorize?response_type=code&client_id=666RVZJTAを 含むLocationヘッダーで、ユーザーをA-ASの認可エンドポイントへリダイレクトする。
  3. ユーザーのブラウザーが攻撃者の認可エンドポイントへ移動すると、 攻撃者は直ちにブラウザーをH-ASの認可エンドポイントへリダイレクトする。 認可リクエストにおいて、攻撃者はA-ASにおけるクライアントのクライアントIDを、 H-ASにおけるクライアントのIDへ置き換える。したがって、ブラウザーは、 https://honest.as.example/authorize?response_type=code&client_id=7ZGZldHQを 指すLocationヘッダーを持つリダイレクト(303 See Other)を受け取る。
  4. ユーザーは、H-ASにおける自身のリソースへ クライアントがアクセスすることを認可する。(注意深いユーザーはこの時点で、 A-ASではなくH-ASを使用していることを意図に反していると検出できる可能性がある。 最初に列挙した攻撃の変種にはこの制限はない。)H-ASはコードを発行し、 (ブラウザー経由で)それをクライアントへ送り返す。

  5. クライアントは、そのコードがA-ASによって発行されたものと 依然として仮定しているため、A-ASのトークンエンドポイントでコードを引き換えようとする。

  6. したがって、攻撃者はコードを取得し、 (パブリッククライアントの場合)コードをアクセストークンと交換するか、 Section 4.5で説明される 認可コードインジェクション攻撃を実行できる。

変種。

  • 傍受を伴うMix-Up: この変種は、 攻撃者が、ユーザーのブラウザーからクライアントへの最初のリクエスト/レスポンスペア (ユーザーが特定の認可サーバーを選択し、その後クライアントによってその認可サーバーへ リダイレクトされるもの)を傍受し操作できる場合にのみ機能する。 これは攻撃者(A2)Section 3を参照)の場合である。 この能力は、たとえば、ユーザーのクライアントへの接続に対する中間者攻撃の結果であり得る。 この攻撃では、ユーザーはH-ASでフローを開始する。攻撃者はこのリクエストを傍受し、 ユーザーの選択をA-ASへ変更する。攻撃の残りは、上記の Step 2以降と同様に進行する。
  • インプリシットグラント: インプリシットグラントでは、 攻撃者はStep 4でコードの代わりにアクセストークンを受け取る。 クライアントがA-ASのuserinfoエンドポイント([OpenID.Core]で定義) へリクエストを行うか、攻撃者のリソースサーバーへリクエストを行うと、 攻撃者の認可サーバーはアクセストークンを受け取る (クライアントはA-ASとのフローを完了したと信じているため)。
  • ASごとのリダイレクトURI: クライアントが 認可サーバーごとに異なるリダイレクトURIを使用し、クライアントが選択された 認可サーバーをユーザーのセッションに保存せず、認可サーバーがリダイレクトURIを 適切に検査しない場合、攻撃者は「Cross Social-Network Request Forgery」と呼ばれる 攻撃を仕掛けることができる。これらの攻撃は実際に観察されている。 詳細については[research.jcs_14]を参照。
  • OpenID Connect: 一部の変種は OpenID Connectを攻撃するために使用できる。これらの攻撃では、攻撃者は OpenID Connect Discovery [OpenID.Discovery]機構の機能を悪用するか、 アクセストークンまたはID TokenをリプレイしてMix-Up攻撃を実行する。 攻撃は[arXiv.1704.08539]のAppendix Aおよび [arXiv.1508.04324v2]のSection 6 ("Malicious Endpoints Attacks")で詳細に説明されている。

4.4.2. 対策

OAuthクライアントが1つの認可サーバーとしかやり取りできない場合、 Mix-Up防御は必要ない。しかし、OAuthクライアントが2つ以上の認可サーバーとやり取りする シナリオでは、クライアントはMix-Up攻撃を防止 MUSTしなければならない。以下では2つの異なる方法を論じる。

両方の防御において、クライアントは認可リクエストごとに、 認可リクエストを送信した発行者を保存し、この情報をユーザーエージェントへ結び付け MUSTなければならない。発行者は、関連するメタデータを通じて、 フローで使用される認可エンドポイントとトークンエンドポイントの組み合わせを示す 抽象識別子として機能する。発行者識別子が利用できない場合(たとえば、 OAuth Authorization Server Metadata [RFC8414]もOpenID Connect Discovery [OpenID.Discovery]も使用されていない場合)、 このタプルの別の一意な識別子またはタプル自体を代わりに使用できる。 表示を簡潔にするため、以下ではそのようなデプロイメント固有の識別子を 発行者(または発行者識別子)に含めて扱う。

認可サーバーURLを保存するだけではMix-Up攻撃を識別するには 不十分である点に注意することが重要である。攻撃者は、侵害されていない認可サーバーの 認可エンドポイントURLを「自分の」認可サーバーURLとして宣言しつつ、 自身の制御下にあるトークンエンドポイントを宣言する可能性がある。

4.4.2.1. 発行者識別による Mix-Up防御

この防御は、認可サーバーがその発行者識別子を 認可レスポンスでクライアントへ送信することを要求する。 認可レスポンスを受信したとき、クライアントは受信した発行者識別子を 保存済みの発行者識別子と比較 MUSTしなければならない。不一致がある場合、クライアントは やり取りを中止 MUSTしなければならない。

この発行者識別子をクライアントへ伝送する方法はいくつかある。

  • 発行者情報は、たとえば [RFC9207]で定義される 別個のレスポンスパラメーターissを介して伝送できる。
  • OpenID Connectが使用され、 ID Tokenが認可レスポンスで返される場合、クライアントはID Token内の issクレームを評価できる。

どちらの場合も、iss値は [RFC9207]に従って評価 MUSTされる。

この防御は、発行者情報を伝送するための新しいOAuth機能の デプロイを必要とする可能性があるが、Mix-Upに対する堅牢で比較的単純な防御である。

4.4.2.2. 個別のリダイレクトURIによる Mix-Up防御

この防御では、クライアントは、やり取りする各発行者について 個別のリダイレクトURIを使用 MUSTしなければならない。

クライアントは、発行者のための個別のリダイレクトURIと、 認可レスポンスが受信されたURIとを比較することで、認可レスポンスが正しい 発行者から受信されたことを検査 MUSTしなければならない。不一致がある場合、クライアントは フローを中止 MUSTしなければならない。

この防御は既存のOAuth機能に基づいているが、 (一部のオープンバンキングスキームのように)多くの異なる発行者の使用のために クライアントが一度だけ登録するシナリオでは使用できず、クライアント登録との密な統合のため、 自動的にデプロイすることがより困難である。

さらに、攻撃者は、この防御が提供する保護を回避できる可能性がある。 すなわち、クライアントが攻撃者の認可サーバーに割り当てたリダイレクトURIを使用して、 「正直な」認可サーバーに新しいクライアントを登録することである。 その後、攻撃者は上記のように攻撃を実行し、クライアントIDを新しく作成した クライアントのクライアントIDへ置き換えることができる。

したがって、この防御は、他の選択肢が利用できない場合にのみ 使用される SHOULDである。

4.5. 認可コード インジェクション

認可レスポンスに含まれる認可コードへアクセスできるようになった攻撃者 (Section 3攻撃者(A3)を参照)は、 認可コードをアクセストークンと交換しようとしたり、その他の方法で 認可コードを利用しようとしたりできる。

認可コードがパブリッククライアント用に作成された場合、 攻撃者は認可コードを認可サーバーのトークンエンドポイントへ送信し、 それによってアクセストークンを取得できる。この攻撃は Section 4.4.1.1 of [RFC6819]で説明されている。

コンフィデンシャルクライアントの場合、または一部の特殊な状況では、 攻撃者は以下で説明するように認可コードインジェクション攻撃を実行できる。

認可コードインジェクション攻撃では、攻撃者は盗まれた認可コードを クライアントにおける攻撃者自身のセッションへ注入しようとする。 その目的は、クライアントにおける攻撃者のセッションを被害者のリソースまたは アイデンティティに関連付け、それによって攻撃者に少なくとも限定的な 被害者のリソースへのアクセスを与えることである。

コンフィデンシャルクライアントのクライアント認証を回避することのほか、 この攻撃のユースケースには次のものが含まれる。

  • 攻撃者がこの特定のクライアントの特定機能へ アクセスしたい場合。例として、攻撃者が特定のアプリまたは特定のWebサイトで 被害者になりすましたい場合がある。
  • 認可サーバーまたはリソースサーバーが、 攻撃者が直接アクセスできない特定のネットワークに限定されている場合。

これらの特殊なケースを除き、コードがパブリッククライアント用に 作成されている場合、認可コードインジェクションは通常あまり魅力的ではない。 上記で説明したように、コードをトークンエンドポイントへ送信する方がより単純で強力な攻撃であるためである。

4.5.1. 攻撃の 説明

認可コードインジェクション攻撃は次のように機能する。

  1. 攻撃者は認可コードを取得する (Section 3攻撃者(A3)を参照)。 攻撃の残りについては、Web攻撃者(A1)の能力だけが必要である。
  2. 攻撃者のデバイスから、攻撃者は正当なクライアントとの 通常のOAuth認可プロセスを開始する。
  3. 認可サーバーから正当なクライアントへのレスポンスにおいて、 攻撃者は新しく作成された認可コードを盗まれた認可コードへ置き換える。 このレスポンスは攻撃者のデバイスを通過しているため、攻撃者はこの目的のために 認可レスポンスを傍受および操作できる任意のツールを使用できる。 攻撃者はネットワークを制御する必要はない。
  4. 正当なクライアントは、redirect_uriおよび クライアントのクライアントIDとクライアントシークレット(または他のクライアント認証手段)とともに、 コードを認可サーバーのトークンエンドポイントへ送信する。
  5. 認可サーバーは、クライアントシークレット、コードが特定のクライアントへ 発行されたかどうか、および実際のリダイレクトURIがredirect_uriパラメーターと 一致するかどうかを検査する([RFC6749]を参照)。
  6. すべての検査が成功し、認可サーバーはアクセストークンおよび その他のトークンをクライアントへ発行する。攻撃者は、正当なクライアントとの自身の セッションを、被害者のリソースおよび/またはアイデンティティに関連付けたことになる。

4.5.2. 考察

明らかに、コードが別のクライアントID、 たとえば攻撃者が設定したクライアントに発行されていた場合、チェックインステップ (Step 5)は失敗する。 認可コードが正当なユーザーによってすでに引き換えられ、一回限りの使用であった場合も、 検査は失敗する。

認可サーバーが認可リクエストで使用された完全な リダイレクトURIを保存し、それをredirect_uriパラメーターと比較する場合、 操作されたリダイレクトURIを介して取得されたコードを注入しようとする試みも検出されるべきである。

Section 4.1.3 of [RFC6749]は、認可サーバーに次を要求している。

初期認可リクエストに"redirect_uri"パラメーターが含まれていた場合、 Section 4.1.1で説明されるように "redirect_uri"パラメーターが存在することを保証し、含まれる場合には それらの値が同一であることを保証する。

Section 4.5.1で説明した攻撃シナリオでは、 正当なクライアントは、認可リクエストに常に使用する正しいリダイレクトURIを使用する。 しかし、このURIは攻撃者によって使用された改ざん済みリダイレクトURIと一致しない (一致するなら、リダイレクトは攻撃者のページへ到達しないため)。 そのため、認可サーバーは攻撃を検出し、コードの交換を拒否する。

この検査は、特定の条件が満たされる場合、 別のデバイス上の同じクライアントの別インスタンスから取得された認可コードを 注入しようとする試みも検出できる。

  • リダイレクトURI自体がnonceまたは別種の 一回限り使用の秘密データを含むこと。および
  • クライアントがこのデータを当該クライアントの この特定インスタンスに結び付けていること。

しかし、このアプローチは、認可エンドポイントで厳密な リダイレクトURI照合を強制するという考えと衝突する。さらに、 プロバイダーがこの段階でredirect_uri検査要件を無視することが非常に多いことが 観察されている。おそらく、仕様を読む限りそれがセキュリティ上重要であるように 見えないためである。

他のプロバイダーは、redirect_uriパラメーターを 登録済みリダイレクトURIパターンと単にパターン照合するだけである。 これにより、認可サーバーは、各トランザクションについて実際のリダイレクトURIと 対応する認可コードとのリンクを保存する必要がなくなる。しかし、この種の検査は、 改ざん済みリダイレクトURIが考慮されないため、仕様の意図を明らかに満たしていない。 したがって、正当なクライアントのclient_idを使用して、または別のデバイス上で 正当なクライアントを利用して取得された認可コードを注入しようとする試みは、 それぞれのデプロイメントで検出されない。

Section 4.1.3 of [RFC6749]で定義される要件は、 クライアントがトークンエンドポイント呼び出しのために正しいリダイレクトURIを 保存または再構築する必要があるため、クライアント実装の複雑さを高めるとも想定される。

クライアント認証のための非対称方式は、この攻撃を止めない。 正当なクライアントがトークンエンドポイントで認証するためである。

したがって、本文書は代わりに、次に説明する機構のいずれかを使用し、 特定のトランザクションの文脈において、各認可コードを特定のデバイス上の (または特定のユーザーエージェント内の)特定のクライアントインスタンスに 結び付けることを推奨する。

4.5.3. 対策

認可コードをクライアントインスタンスに結び付けるには、 次の2つの優れた技術的解決策がある。

4.5.3.1. PKCE

[RFC7636]で規定されるPKCE機構は、 (もともとはネイティブアプリを保護するために設計されたものの)対策として使用できる。 攻撃者が認可コードを注入しようとすると、code_verifierの検査は失敗する。 クライアントは自身の正しいverifierを使用するが、そのコードはこのverifierと一致しない code_challengeに関連付けられているためである。

PKCEは認可コードインジェクション攻撃を防ぐだけでなく、 パブリッククライアント用に作成された認可コードも保護する。PKCEは、 攻撃者がcode_verifierを知らずに、認可サーバーのトークンエンドポイントで 盗まれた認可コードを引き換えられないことを保証する。

4.5.3.2. Nonce

OpenID Connectの既存のnonceパラメーターは、 認可コードインジェクション攻撃から保護できる。nonce値は一回限り使用であり、 クライアントによって作成される。クライアントはそれをユーザーエージェントセッションに 結び付け、OpenID Provider (OP)への初期リクエストとともに送信することになっている。 OPは受信したnonce値を、トークンエンドポイントでのコード交換の一部として 発行されるID Tokenに入れる。 攻撃者が認可レスポンスに 認可コードを注入した場合、クライアントセッション内のnonce値と、トークンエンドポイントから 受信したID Token内のnonce値は一致せず、攻撃は検出される。 この仮定は、攻撃者が(対応する認可コードを盗んだ)被害者のデバイス上の ユーザーエージェント状態を取得できないというものである。

この対策は、クライアントがトークンエンドポイントから取得した ID Token内のnonceパラメーターを適切に検査し、その検査が成功するまで 発行されたトークンを一切使用しない場合にのみ機能する点に注意することが重要である。 より正確には、nonceパラメーターを用いてコードインジェクションから自身を保護する クライアントは、次を行う。

  1. トークンエンドポイントから取得したID Token内のnonceを検証 MUSTしなければならない。 これは、別のID Tokenが認可レスポンスから取得されていた場合 (たとえばresponse_type=code+id_token)でも同様である。および
  2. その検査が成功しない限り、また成功するまで、すべてのトークン (ID Tokenおよびアクセストークン)が無視され、他の目的に使用されないことを保証 MUSTしなければならない。

nonceはパブリッククライアントの 認可コードを保護しない点に注意することが重要である。 攻撃者は認可コードインジェクション攻撃を実行する必要がないためである。 代わりに、攻撃者は盗まれた認可コードを用いてトークンエンドポイントを直接呼び出すことができる。

4.5.3.3. その他の 解決策

stateをコードに結び付けること、 暗号的手段を用いてコードに送信者制約を付けること、またはインスタンスごとの クライアントクレデンシャルなど、他の解決策も考えられるが、 サポートが不足しており、新たなセキュリティ要件をもたらす。

PKCEは執筆時点で利用可能であるため、OAuthクライアントにとって 最も明白な解決策であり、nonceはOpenID Connectクライアントに適している。

4.5.4. 制限事項

攻撃者が、被害者の認可リクエストで使用されるnonce値または code_challenge値を変更できる場合、上記の対策を回避できる。 攻撃者は、これらの値を、上記攻撃のStep 2で 自身のセッションにおいてクライアントが選んだものと同じ値へ変更できる。 (これは、被害者のクライアントとのセッションが、攻撃者がクライアントとのセッションを 開始した後に始まることを必要とする。)その後、攻撃者が被害者から認可コードを 捕捉できる場合、PKCEまたはnonceが使用されていても、攻撃者は Step 3で盗まれたコードを注入できる。

この攻撃は複雑であり、攻撃者と被害者のセッションの間に 密接な相互作用を必要とする。それにもかかわらず、認可レスポンスの内容を 攻撃者が読み取ることを防ぐための対策は、Sections 4.14.24.34.4、および4.11で説明されるように、なお講じる必要がある。

4.6. アクセストークンインジェクション

アクセストークンインジェクション攻撃では、攻撃者は盗まれた アクセストークンを(攻撃者の制御下にない)正当なクライアントへ注入しようとする。 これは通常、攻撃者が漏えいしたアクセストークンを利用して、特定のクライアントで ユーザーになりすましたい場合に発生する。

攻撃を実行するために、攻撃者はインプリシットグラントを使用して クライアントとのOAuthフローを開始し、認可サーバーが発行したアクセストークンを 置き換えることで認可レスポンスを変更するか、漏えいしたアクセストークンを含む 認可サーバーレスポンスを直接作り上げる。レスポンスには、この特定のトランザクションのために クライアントが生成したstate値が含まれるため、クライアントはそのレスポンスを CSRF攻撃として扱わず、攻撃者が注入したアクセストークンを使用する。

4.6.1. 対策

純粋なOAuthフローでは、このようなインジェクション攻撃を検出する方法はない。 トークンがトランザクションまたは特定のユーザーエージェントへの結び付けなしに 発行されるためである。

OpenID Connectでは、認可レスポンスにat_hashクレームを 含むID Tokenが追加で含まれるため、この攻撃を緩和できる。したがって、攻撃者は レスポンス内のアクセストークンとID Tokenの両方を置き換える必要がある。 ID Tokenは認証を伴って署名または暗号化されているため、攻撃者はID Tokenを偽造できない。 また、漏えいしたID Token内のnonceクレームは、認可レスポンスで期待される値とは (非常に高い確率で)異なる値を含むため、攻撃者は盗まれたアクセストークンに一致する 漏えいID Tokenを注入することもできない。

攻撃者がアクセストークンをリソースエンドポイントで直接使用することを防ぐには、 送信者制約付きアクセストークンのような追加の保護がなお必要である点に注意すること。

Section 2.1.2の推奨事項はこれに由来する。

4.7. クロスサイトリクエスト フォージェリ

攻撃者は、被害者のデバイス上の正当なクライアントの リダイレクトURIへリクエストを注入しようとする可能性がある。たとえば、 クライアントに攻撃者の制御下にあるリソースへアクセスさせるためである。 これはCross-Site Request Forgery (CSRF)として知られる攻撃の変種である。

4.7.1. 対策

長く確立された対策は、クライアントが stateパラメーター内にCSRF Tokenとしても知られるランダム値を渡し、 説明されるように、リダイレクトURIへのリクエストをユーザーエージェントセッションへ 関連付けることである。この対策はSection 5.3.5 of [RFC6819]で 詳細に説明されている。同じ保護は、PKCEまたはOpenID Connectのnonce値によって提供される。

CSRF保護のためにstateまたはnonceの代わりに PKCEを使用する場合、次の点に注意することが重要である。

  • クライアントは、CSRF保護のためにPKCEを使用する前に、 認可サーバーがPKCEをサポートしていることを保証 MUSTしなければならない。 認可サーバーがPKCEをサポートしていない場合、CSRF保護にはstateまたは nonceを使用 MUSTしなければならない。

  • stateがアプリケーション状態を運ぶために使用され、 その内容の完全性が懸念される場合、クライアントはstateを 改ざんおよびすり替えから保護 MUSTしなければならない。 これは、stateの内容をブラウザーセッションに結び付けること、および/または state値に署名/暗号化することで達成できる。この一例は、期限切れのInternet-Draft [JWT-ENCODED-STATE]で論じられている。

したがって、認可サーバーはPKCEサポートを検出する方法を提供 MUSTしなければならない。 [RFC8414]に従って Authorization Server Metadataを使用することが RECOMMENDEDであるが、認可サーバーは代わりに、 PKCEサポートを保証または判定するデプロイメント固有の方法を提供 MAYできる。

PKCEは、認可レスポンスを読み取ることができる攻撃者 (Section 3攻撃者(A3)を参照)が存在する場合でも、 CSRF攻撃に対する堅牢な保護を提供する。stateが使用される場合、またはID Tokenが 認可レスポンスで返される場合(たとえばresponse_type=code+id_token)、 攻撃者はstate値を知って偽造された認可レスポンスにそれをリプレイできるか、 ID Tokenからnonceを抽出し、それを新しいリクエストで認可サーバーへ使用して 同じnonceを持つID Tokenを生成できる。その新しいID Tokenは、その後CSRF攻撃に使用できる。

4.8. PKCEダウングレード攻撃

PKCEをサポートしているものの、すべてのフローでその使用を必須としていない 認可サーバーは、PKCEダウングレード攻撃を受けやすい可能性がある。

この攻撃の第一の前提条件は、特定のフローについてPKCEを有効化または 無効化する、攻撃者が制御可能なフラグが認可リクエスト内に存在することである。 code_challengeパラメーターの存在または不在はこの目的に適している。 すなわち、このパラメーターが認可リクエストに存在する場合、認可サーバーは PKCEを有効化し強制するが、パラメーターが欠落している場合にはPKCEを強制しない。

この攻撃の第二の前提条件は、クライアントがstateをまったく 使用していないこと(たとえば、クライアントがCSRF防止にPKCEへ依存しているため)、 またはクライアントがstateを正しく検査していないことである。

大まかに言えば、この攻撃はCSRF攻撃の変種である。 攻撃者は、Section 4.7で説明された攻撃と同じ目標を達成する。 すなわち、攻撃者は、攻撃者のリソースに結び付いた認可コード (そしてそれによりアクセストークン)を、被害者とクライアントの間のセッションへ注入する。

4.8.1. 攻撃の 説明

  1. ユーザーは、認可サーバーで何らかのクライアントを使用して OAuthセッションを開始している。認可リクエストにおいて、クライアントは PKCE code challengeとしてcode_challenge=hash(abc)パラメーターを設定している (ハッシュ関数およびパラメーターエンコーディングは[RFC7636]で定義されるとおり)。 クライアントは現在、ユーザーのブラウザーから認可レスポンスを受信するのを待っている。
  2. 攻撃を実行するために、攻撃者は自身のデバイスを使用して 対象クライアントとの認可フローを開始する。クライアントは今度は別の PKCE code challenge、たとえばcode_challenge=hash(xyz)を認可 リクエストで使用する。攻撃者はそのリクエストを傍受し、 code_challengeパラメーター全体をリクエストから削除する。 このステップは攻撃者のデバイス上で実行されるため、攻撃者は たとえばブラウザーデバッグツールを使用して、リクエスト内容へ完全にアクセスできる。
  3. 認可サーバーがPKCEなしのフローを許可する場合、 PKCE code challengeに結び付けられていないコードを作成する。
  4. 攻撃者はここで、認可サーバーとの攻撃者のセッション用のコードを 含む認可レスポンスURLへユーザーのブラウザーをリダイレクトする。
  5. ユーザーのブラウザーは認可コードをクライアントへ送信し、 クライアントは認可サーバーでコードをアクセストークンと交換しようとする。 クライアントはトークンリクエスト内でPKCE code verifierとして code_verifier=abcを送信する。
  6. 認可サーバーは、このコードがいかなるPKCE code challengeにも結び付けられていないことを確認するため、 code_verifierパラメーターの存在または内容を検査しない。 認可サーバーは、攻撃者のリソースに属するアクセストークンを、ユーザーの制御下にある クライアントへ発行する。

4.8.2. 対策

stateを適切に使用すれば、この攻撃を防止できる。 しかし、実務上、多くのOAuthクライアントがstateを使用していない、 または適切に検査していないことが示されている。

したがって、認可サーバーはこの攻撃を緩和 MUSTしなければならない。

認可サーバーの観点からは、上記の攻撃では、 その認可コードが発行されたOAuthフローの認可リクエストに code_challengeパラメーターが存在しなかったにもかかわらず、 トークンエンドポイントでcode_verifierパラメーターが受信される点に注意すること。

この事実は、この攻撃を緩和するために使用できる。 [RFC7636]はすでに次を義務付けている。

  • PKCEをサポートする認可サーバーは、 認可リクエストにcode challengeが含まれているかどうかを検査し、 この情報を発行されるコードに結び付け MUSTる。および
  • コードがトークンエンドポイントに到着し、 このコードが発行された認可リクエストにcode_challengeが存在した場合、 トークンリクエストには有効なcode_verifierが存在しなければならない。

これに加えて、PKCEダウングレード攻撃を防止するため、 認可サーバーは、認可リクエストにcode_challengeが存在しなかった場合、 code_verifierを含むトークンエンドポイントへのリクエストが拒否されることを保証 MUSTしなければならない。

PKCEの使用を(一般に、または特定のクライアントについて) 義務付ける認可サーバーは、このセキュリティ対策を暗黙的に実装している。

4.9. リソースサーバーにおける アクセストークン漏えい

アクセストークンは、特定の状況下でリソースサーバーから漏えいする可能性がある。

4.9.1. 偽造リソースサーバーによる アクセストークンフィッシング

攻撃者は自身のリソースサーバーを設定し、 他のリソースサーバーに対して有効なアクセストークンをそこへ送信するよう クライアントをだます可能性がある (Section 3の攻撃者 (A1)および (A5)を参照)。 クライアントが有効なアクセストークンをこの偽造リソースサーバーへ送信した場合、 攻撃者はそのトークンを使用して、リソース所有者に代わって他のサービスへアクセスできる。

この攻撃は、クライアントが開発時に1つの特定のリソースサーバー (およびそのURL)に結び付けられておらず、クライアントインスタンスに実行時に リソースサーバーURLが提供されることを仮定している。 この種の遅延バインディングは、クライアントが標準化されたAPI (たとえばメール、カレンダー、eHealth、またはオープンバンキング向け)を実装するサービスを 使用し、クライアントがユーザーまたは管理者によって設定される状況で典型的である。

4.9.2. 侵害された リソースサーバー

攻撃者は、特定のデプロイメントのリソースへアクセスするために リソースサーバーを侵害する可能性がある。このような侵害は、たとえばログファイルへの 部分的なアクセスから、当該サーバーの完全な制御まで幅があり、その場合、すべての制御を 回避し、すべてのリソースへアクセスできる。 攻撃者はまた、侵害されたシステム上に保持され、他のリソースサーバーへの アクセスに有効である可能性のある他のアクセストークンも取得できる。

サーバーシステムの堅牢化と監視によってサーバー侵害を防止することは、 標準的な運用手順と見なされるため、本文書の範囲外である。 Section 4.9は、 OAuth関連の侵害の影響と、捕捉されたアクセストークンのリプレイに焦点を当てる。

4.9.3. 対策

悪意ある行為者によるアクセストークンリプレイに対処するため、 実装者は次の対策を考慮すべきである。

  • Section 4.10.1で 説明される送信者制約付きアクセストークンを使用 SHOULDして、攻撃者が他のリソースサーバー上で アクセストークンをリプレイすることを防止する。攻撃者が、Webサーバーログへの 読み取り専用アクセスのように、侵害されたシステムへの部分的なアクセスしか持たない場合、 送信者制約付きアクセストークンは侵害されたシステム上でのリプレイも防止できる可能性がある。
  • Section 4.10.2で 説明されるオーディエンス制限を使用 SHOULDして、 捕捉されたアクセストークンの他のリソースサーバー上でのリプレイを防止する。
  • リソースサーバーは、アクセストークンを 他の機微な秘密と同様に扱い、平文で保存または転送しては MUSTならない。

第一および第二の推奨事項は、アクセストークンが漏えいする他の シナリオにも適用される(Section 3攻撃者(A5)を参照)。

4.10. 盗まれた アクセストークンの悪用

アクセストークンは、たとえばSections 4.14.24.34.4、および 4.9で説明される攻撃を通じて、 さまざまな方法で攻撃者に盗まれる可能性がある。これらの攻撃の一部は、それぞれのセクションで 説明される特定のセキュリティ対策によって緩和できる。しかし、場合によっては、 これらの対策が十分でない、または正しく実装されていないことがある。 したがって、認可サーバーは、以下で説明するようにアクセストークンが送信者制約付きであり、 オーディエンス制限付きであることを保証 SHOULDする。アーキテクチャ上および性能上の理由により、 一部のデプロイメントではこれらの対策の使用が妨げられる可能性がある。

4.10.1. 送信者制約付きアクセストークン

名前が示すように、送信者制約付きアクセストークンは、 アクセストークンの適用範囲を特定の送信者に限定する。 この送信者は、リソースサーバーでそのトークンが受け入れられる前提条件として、 特定の秘密を知っていることを示す義務を負う。

典型的なフローは次のようになる。

  1. 認可サーバーは、この特定のトークンを 特定のクライアントに結び付けるデータをアクセストークンに関連付ける。 この結び付けにはクライアントのアイデンティティを利用できるが、多くの場合、 認可サーバーはクライアントが知っている鍵素材(または鍵素材から導出されたデータ)を利用する。
  2. この鍵素材は何らかの方法で配布されなければならない。 鍵素材は認可サーバーが結び付けを作成する前からすでに存在している場合もあれば、 認可サーバーがエフェメラル鍵を作成する場合もある。既存の鍵素材の配布方法は、 アプローチによって異なる。たとえば、X.509証明書を使用でき、その場合、 配布は登録プロセス中に明示的に行われる。または、鍵素材がTLSレイヤーで 作成および配布される場合もあり、その場合、TLS接続の設定中に自動的に行われる可能性がある。
  3. リソースサーバーは、実際の所有証明検査を実装しなければならない。 これは通常、アプリケーションレベルで行われ、多くの場合、トランスポート層 (たとえばTLS)から提供される特定の素材に結び付けられる。リソースサーバーは、 所有証明のリプレイが不可能であることも保証しなければならない。

所有証明を使用する送信者制約付きアクセストークンの方法として、 OAuthワーキンググループによって定義され、実際に使用されているものが2つある。

  • "OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens" [RFC8705]: この文書で規定されるアプローチは、クライアント認証と送信者制約付きアクセストークンの 両方に相互TLSを使用することを可能にする。送信者制約付きアクセストークンの目的では、 クライアントはその公開鍵のフィンガープリントによってリソースサーバーに対して識別される。 アクセストークンリクエストの処理中、認可サーバーはTLSスタックからクライアントの 公開鍵を取得し、そのフィンガープリントを対応するアクセストークンと関連付ける。 リソースサーバーも同様にTLSスタックから公開鍵を取得し、そのフィンガープリントを アクセストークンに関連付けられたフィンガープリントと比較する。
  • "OAuth 2.0 Demonstrating Proof of Possession (DPoP)" [RFC9449]: DPoPは、アクセストークンおよびリフレッシュトークンに送信者制約を付けるための アプリケーションレベルの機構を概説する。これは、公開/秘密鍵ペアと アプリケーションレベルの署名に基づく所有証明を使用する。DPoPは パブリッククライアントで使用でき、コンフィデンシャルクライアントの場合には、 任意のクライアント認証方式と組み合わせることができる。

攻撃者がトークンと鍵素材の両方にアクセスできるようになると、 送信者制約付きトークンのセキュリティは損なわれる点に注意すること。 これは特に、破損したクライアントソフトウェアや(クライアントがブラウザー内で実行されている場合の) クロスサイトスクリプティング攻撃に該当する。鍵素材がハードウェアまたはソフトウェアの セキュリティモジュール内で保護されている、または(TLSスタックのように)間接的にしか アクセスできない場合、送信者制約付きトークンは少なくとも、クライアントがオフラインのとき、 すなわちセキュリティモジュールまたはインターフェイスが攻撃者に利用できないときに、 トークンの使用から保護する。これはアクセストークンだけでなくリフレッシュトークンにも適用される (Section 4.14を参照)。

4.10.2. オーディエンス制限付きアクセストークン

オーディエンス制限は、本質的にアクセストークンを 特定のリソースサーバーに制限する。認可サーバーはアクセストークンを 特定のリソースサーバーに関連付け、リソースサーバーは意図されたオーディエンスを 検証することになっている。アクセストークンが意図されたオーディエンスの検証に失敗した場合、 リソースサーバーは対応するリクエストの処理を拒否する。

一般に、オーディエンス制限はトークン漏えいの影響を制限する。 偽造リソースサーバーの場合には、以下で説明するように、フィッシングされたアクセストークンが 正当なリソースサーバーで悪用されることも防止できる可能性がある。

オーディエンスは、論理名または物理アドレス (URLなど)を用いて表現できる。フィッシングを防止するには、クライアントが リクエストを送信する実際のURLを使用する必要がある。フィッシングの場合、 このURLは偽造リソースサーバーを指す。攻撃者がアクセストークンを正当な リソースサーバー(異なるURLを持つ)で使用しようとすると、リソースサーバーは 不一致(誤ったオーディエンス)を検出し、リクエストの処理を拒否する。

認可サーバーがすべてのリソースサーバーのURLを知っている デプロイメントでは、認可サーバーは未知のリソースサーバーURLに対する アクセストークンの発行を単に拒否してもよい。

これが機能するためには、クライアントは意図するリソースサーバーを 認可サーバーに伝える必要がある。このために[RFC8707]の機構を使用できるか、または 情報をscope値(Section 3.3 of [RFC6749])に エンコードできる。

URLの代わりに、リソースサーバーのX.509証明書の フィンガープリントをオーディエンス値として利用することも可能である。 この変種では、異なるCAから取得した有効なTLS証明書を使用して正当なリソースサーバーの URLを偽装しようとする試みも検出できる。リソースサーバーURLを認可サーバーから 隠すことは、プライバシー上の利点とも見なされ得る。

オーディエンス制限は、クライアント側で暗号を必要としないため、 より使いやすく見えるかもしれない。それでも、各アクセストークンが特定の リソースサーバーに結び付けられるため、クライアントは複数のリソースサーバーへ アクセスする際、単一のリソースサーバー固有のアクセストークンも取得する必要がある。 ([RFC8707]で規定される resource indicatorsは、これを達成するのに役立つ。) [TOKEN-BINDING]も、異なるtoken-binding IDを アクセストークンに関連付ける必要があるため、同じ性質を持っていた。 一方、OAuth 2.0の相互TLS [RFC8705]を使用すると、クライアントは複数の リソースサーバーでアクセストークンを使用できる。

オーディエンス制限、または一般的に言えば、 クライアントがアクセストークンをどこで使用したいかを認可サーバーに示すことは、 トークン漏えい防止の範囲を超える追加の利点を持つ点に注意すべきである。 それらにより、認可サーバーは、当該サーバー向けに特化して作成された形式および内容を持つ 異なるアクセストークンを作成できる。これは、構造化アクセストークンを使用する デプロイメントにおいて、大きな機能上およびプライバシー上の利点を持つ。

4.10.3. 考察: メタデータを介した漏えいの防止

認可サーバーは、アクセストークンを安全に使用できる場所について 追加情報をクライアントへ提供できる。このアプローチと、それが推奨されない理由を 以下で論じる。

最も単純な形では、認可サーバーが既知のリソースサーバーのリストを 公開する必要がある。次の例は、非標準のAuthorization Server Metadataパラメーター resource_serversを使用して示している。

HTTP/1.1 200 OK
Content-Type: application/json

{
  "issuer":"https://server.somesite.example",
  "authorization_endpoint":
    "https://server.somesite.example/authorize",
  "resource_servers":[
    "email.somesite.example",
    "storage.somesite.example",
    "video.somesite.example"
  ]
  ...
}

認可サーバーは、アクセストークンが有効なURLを トークンレスポンスで返すこともできる。次の例は、非標準の戻りパラメーター access_token_resource_serverを使用して示している。

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
  "access_token":"2YotnFZFEjr1zCsicMWpAA",
  "access_token_resource_server":
    "https://hostedresource.somesite.example/path1",
...
}

この緩和戦略は、クライアントがセキュリティポリシーを強制し、 正当な宛先にのみアクセストークンを送信することに依存する。 OAuth関連のセキュリティ研究の結果(たとえば [research.ubc]および [research.cmu]を参照)は、 クライアント実装の大部分が、state検査のようなセキュリティ制御を 実装していない、または適切に実装できていないことを示している。 したがって、アクセストークンフィッシングの防止をクライアントに依存することも 失敗する可能性が高い。さらに、クライアントと認可サーバーおよびリソースサーバーの 比率を考えると、セキュリティ関連ロジックを可能な限りこれらのサーバーへ移すことが より実現可能なアプローチと見なされる。 明らかに、クライアントは全体的なセキュリティに貢献しなければならない。 しかし、4.10.1および4.10.2で説明されるような、関係当事者間の より良いバランスを提供する代替対策がある。

4.11. オープンリダイレクション

認可サーバーまたはクライアントにオープンリダイレクターがある場合、 次の攻撃が発生し得る。そのようなエンドポイントは、たとえばユーザーが外部Webサイトへ リダイレクトされる前にメッセージを表示するため、またはログインプロンプトなどで中断される前に 訪問しようとしていたURLへユーザーを戻すために実装されることがある。

4.11.1. オープンリダイレクターとしての クライアント

クライアントはオープンリダイレクターを公開しては MUST NOTならない。攻撃者はオープンリダイレクターを使用して、 クライアントを指すURLを生成し、それを利用して Section 4.1.2で説明されるように 認可コードおよびアクセストークンを流出させる可能性がある。 別の悪用ケースは、クライアントを指しているように見えるURLを生成することである。 これにより、ユーザーはそのURLを信頼してブラウザーで開くようだまされる可能性がある。 これはフィッシングに悪用できる。

オープンリダイレクションを防止するため、クライアントは、 ターゲットURLが許可されている場合、またはリクエストの起源および完全性を認証できる場合に のみリダイレクトすべきである。オープンリダイレクションに対する対策は OWASP [owasp.redir]で説明されている。

4.11.2. オープンリダイレクターとしての 認可サーバー

クライアントと同様に、攻撃者はフィッシング攻撃を行うために、 ユーザーの認可サーバー(特にそのURL)への信頼を利用しようとする可能性がある。 OAuth認可サーバーは通常、ユーザーを他のWebサイト(クライアント)へリダイレクトするが、 それを安全に行わなければならない。

Section 4.1.2.1 of [RFC6749]はすでに、 client_idredirect_uriの組み合わせが無効な場合、 認可サーバーがユーザーエージェントを自動的にリダイレクトしては MUST NOTならないと述べることで、オープンリダイレクトを防止している。

しかし、攻撃者は正しく登録されたリダイレクトURIを利用して フィッシング攻撃を行うこともできる。攻撃者は、たとえば動的クライアント登録 [RFC7591]を通じてクライアントを登録し、 次のいずれかの攻撃を実行できる。

  1. たとえば無効なscope値を使用するなどして、 意図的に誤った認可リクエストを送信し、認可サーバーにユーザーエージェントを フィッシングサイトへリダイレクトさせる。
  2. 攻撃者が制御するclient_idおよび redirect_uriを含む有効な認可リクエストを意図的に送信する。 ユーザーが認証した後、認可サーバーはユーザーにリクエストへの同意を促す。 ユーザーがリクエストの問題に気づいて拒否した場合でも、認可サーバーは ユーザーエージェントをフィッシングサイトへリダイレクトする。この場合、 ユーザーエージェントはユーザーが取った行動に関係なくフィッシングサイトへリダイレクトされる。
  3. 攻撃者が制御するclient_idおよび redirect_uriを含む有効なサイレント認証リクエスト (prompt=none)を意図的に送信する。この場合、認可サーバーは ユーザーエージェントをフィッシングサイトへ自動的にリダイレクトする。

認可サーバーは、これらの脅威を防止するための予防措置を講じ MUSTなければならない。認可サーバーは常にまずユーザーを認証し、 サイレント認証ユースケースを除き、ユーザーをリダイレクトする前に、 必要に応じてユーザーにクレデンシャルを求め MUSTなければならない。認可サーバーは、自身のリスク評価に基づき、 リダイレクトURIを信頼できるかどうかを判断する必要がある。認可サーバーは、 URIの背後にあるコンテンツの信頼性および信用性、ならびにリダイレクトURIおよび その他のクライアントデータの出所を評価するために、内部または外部サービスを通じて行われる URI分析を考慮することができる。

認可サーバーは、リダイレクトURIを信頼する場合にのみ ユーザーエージェントを自動的にリダイレクト SHOULDする。URIが信頼されない場合、 認可サーバーはユーザーに通知し、ユーザーが正しい判断を行うことに依存 MAYできる。

4.12. 307リダイレクト

認可エンドポイントでは、典型的なプロトコルフローとして、 認可サーバーがユーザーにフォームでクレデンシャルの入力を促し、そのフォームが (HTTP POSTメソッドを使用して)認可サーバーへ送信される。 認可サーバーはクレデンシャルを検査し、成功した場合、ユーザーエージェントを クライアントのリダイレクトエンドポイントへリダイレクトする。

[RFC6749]では、 この目的にHTTPステータスコード302 (Found)が使用されているが、 「このリダイレクトを達成するためにユーザーエージェントを介して利用可能な他の任意の方法も許可される」。 代わりにステータスコード307がリダイレクトに使用される場合、ユーザーエージェントは ユーザーのクレデンシャルをHTTP POSTでクライアントへ送信する。

これは機微なクレデンシャルをクライアントへ開示する。 クライアントが悪意あるものである場合、認可サーバーでユーザーになりすますために そのクレデンシャルを使用できる。

この挙動は開発者にとって予期しないものかもしれないが、 Section 15.4.8 of [RFC9110]で定義されている。 このステータスコード(307)は、ユーザーエージェントにPOSTリクエストをGETリクエストへ 書き換えることを要求せず、したがってPOSTリクエスト本文内のフォームデータを 削除しない。

HTTP標準[RFC9110]では、ステータスコード303だけが HTTP POSTリクエストをHTTP GETリクエストへ書き換えることを明確に強制する。 一般的な302を含む他のすべてのステータスコードについては、ユーザーエージェントは POSTをGETリクエストへ書き換えないことを選択でき、その結果、ユーザーのクレデンシャルが クライアントに開示される可能性がある。(ただし実際には、多くのユーザーエージェントは この挙動を307リダイレクトに対してのみ示す。)

したがって、ユーザーのクレデンシャルを含む可能性があるリクエストを リダイレクトする認可サーバーは、リダイレクトにHTTP 307ステータスコードを使用しては MUST NOTならない。そのようなリクエストにHTTPリダイレクト (たとえばJavaScriptではなく)が使用される場合、認可サーバーはHTTPステータスコード303 (See Other)を使用 SHOULDする。

4.13. TLS終端 リバースプロキシ

HTTPアプリケーションの一般的なデプロイメントアーキテクチャは、 TLS接続を終端し、受信リクエストを対応するアプリケーションサーバーノードへ ディスパッチするリバースプロキシの背後にアプリケーションサーバーを隠すことである。

本セクションでは、OAuthに関連するこのデプロイメントアーキテクチャの 攻撃角度をいくつか取り上げ、セキュリティ制御に関する推奨事項を示す。

状況によっては、リバースプロキシはさらなる処理のために セキュリティ関連データを上流のアプリケーションサーバーへ渡す必要がある。 例には、リクエスト送信元のIPアドレス、token-binding ID、認証されたTLSクライアント証明書が含まれる。 このデータは通常、上流リクエストに追加されたHTTPヘッダーで渡される。 ヘッダーは多くの場合カスタムのアプリケーション固有ヘッダーであるが、 クライアント証明書およびクライアント証明書チェーンの標準化されたヘッダーフィールドは [RFC9440]で定義されている。

リバースプロキシが外部から送信された任意のヘッダーを通過させる場合、 攻撃者は、その方法でセキュリティ制御を回避するために、偽のヘッダー値を プロキシ経由でアプリケーションサーバーへ直接送信しようとする可能性がある。 たとえば、リバースプロキシがX-Forwarded-Forヘッダーを受け入れ、 受信リクエストの送信元を単に追加する(リストにする)ことは標準的な慣行である。 アプリケーションサーバーで実行されるロジックによっては、攻撃者は単に許可されたIPアドレスを ヘッダーに追加し、保護を無意味にできる可能性がある。

したがって、リバースプロキシは、アプリケーションサーバーの セキュリティに関連するすべてのヘッダー値の真正性および完全性を保証するために、 受信リクエストをサニタイズ MUSTしなければならない。

攻撃者がプロキシとアプリケーションサーバーの間の内部ネットワークへ アクセスできる場合、設置されているセキュリティ制御を回避しようとする可能性もある。 したがって、通信エンティティの真正性を保証することが不可欠である。 さらに、リバースプロキシとアプリケーションサーバーの間の通信リンクは、 メッセージの盗聴、注入、およびリプレイから保護され MUSTなければならない。

4.14. リフレッシュトークンの 保護

リフレッシュトークンは、新しいアクセストークンを取得するための 便利でユーザーフレンドリーな方法である。また、認可サーバーが短い有効期間かつ 縮小されたスコープのアクセストークンを発行できるようにし、アクセストークン漏えいの 潜在的影響を低減するため、OAuthのセキュリティにも寄与する。

4.14.1. 考察

リフレッシュトークンは攻撃者にとって魅力的な標的である。 なぜなら、特定のクライアントに付与されたアクセスの全範囲を表し、 特定のリソースにさらに制約されていないためである。 攻撃者がリフレッシュトークンを流出させ、それを正常にリプレイできる場合、 攻撃者はアクセストークンを発行し、リソース所有者に代わってそれらを使用して リソースサーバーへアクセスできる。

[RFC6749]は、 次を要求することで、すでに堅牢なベースライン保護を提供している。

  • 転送中および保存中のリフレッシュトークンの機密性。
  • 認可サーバーとクライアントの間で TLS保護された接続を介してリフレッシュトークンを送信すること。
  • 可能であれば、認可サーバーが リフレッシュトークンと特定のクライアントとの結び付けを維持および検査し、 トークン更新中にこのクライアントを認証すること。および
  • リフレッシュトークンが生成、変更、または推測できないこと。

[RFC6749]は、 それぞれのエラーコードおよびレスポンス挙動を定義することで、 リフレッシュトークンの有効期限および失効、ならびにリフレッシュトークンローテーションのような さらなる(実装固有の)セキュリティ対策の基盤も築いている。

本仕様は、[RFC6749]の 範囲を超える推奨事項および明確化を提供する。

4.14.2. 推奨事項

認可サーバーは、リスク評価に基づき、特定のクライアントへ リフレッシュトークンを発行するかどうかを判断 MUSTしなければならない。認可サーバーが リフレッシュトークンを発行しないと決定した場合、クライアントは認可コードグラントタイプのような 他のグラントタイプを利用することで新しいアクセストークンを取得 MAYできる。そのような場合、認可サーバーはユーザー体験を最適化するために、 Cookieおよび永続的グラントを利用できる。

リフレッシュトークンが発行される場合、それらのリフレッシュトークンは、 リソース所有者が同意したスコープおよびリソースサーバーに結び付けられ MUSTなければならない。これは、正当なクライアントによる権限昇格を防止し、 リフレッシュトークン漏えいの影響を低減するためである。

コンフィデンシャルクライアントについては、[RFC6749]がすでに、 リフレッシュトークンは発行先のクライアントによってのみ使用できることを要求している。

認可サーバーは、パブリッククライアントについて、 悪意ある行為者によるリフレッシュトークンリプレイを検出するために、次の方法のいずれかを利用 MUSTしなければならない。

  • 送信者制約付きリフレッシュトークン: 認可サーバーは、 たとえば[RFC8705]または[RFC9449]を利用することで、リフレッシュトークンを 特定のクライアントインスタンスへ暗号的に結び付ける。
  • リフレッシュトークンローテーション: 認可サーバーは、アクセストークン更新レスポンスごとに新しいリフレッシュトークンを発行する。 以前のリフレッシュトークンは無効化されるが、関係に関する情報は 認可サーバーに保持される。リフレッシュトークンが侵害され、その後攻撃者と 正当なクライアントの両方によって使用された場合、その一方が無効化された リフレッシュトークンを提示し、それによって認可サーバーに侵害を知らせる。 認可サーバーは、どちらの当事者が無効なリフレッシュトークンを提出したかを 判断できないが、アクティブなリフレッシュトークンを失効させる。 これにより、正当なクライアントに新しい認可グラントを取得させる代償を伴って、 攻撃を停止する。

    実装上の注意: リフレッシュトークンが属するグラントは、 リフレッシュトークン自体にエンコードされてもよい。これにより、認可サーバーは リフレッシュトークンが属するグラント、および拡張して失効させる必要があるすべての リフレッシュトークンを効率的に判断できる。認可サーバーは、この場合、たとえば 署名を使用して、リフレッシュトークン値の完全性を保証 MUSTしなければならない。

認可サーバーは、次のようなセキュリティイベントが発生した場合に、 リフレッシュトークンを自動的に失効 MAYさせることができる。

  • パスワード変更、または
  • 認可サーバーでのログアウト。

クライアントが一定期間非アクティブであった場合、 すなわち、リフレッシュトークンが一定期間新しいアクセストークンの取得に使用されていない場合、 リフレッシュトークンは期限切れになる SHOULDである。有効期限は認可サーバーの裁量に委ねられる。 これはグローバルな値であっても、クライアントポリシーまたはリフレッシュトークンに関連付けられた グラント(およびその機微性)に基づいて決定されてもよい。

4.15. リソース所有者になりすます クライアント

リソースサーバーは、アクセストークンが発行されたリソース所有者の アイデンティティ、またはクライアントクレデンシャルグラントにおけるクライアントの アイデンティティに基づいてアクセス制御判断を行う場合がある。たとえば、 [RFC9068](JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens)は、 次のように定義されたsubクレームを含むアクセストークンのデータ構造を記述している。

認可コードグラントのように、リソース所有者が関与するグラントを通じて アクセストークンが取得される場合、"sub"の値はリソース所有者の subject identifierに対応 SHOULDする。 クライアントクレデンシャルグラントのように、リソース所有者が関与しないグラントを通じて アクセストークンが取得される場合、"sub"の値は、認可サーバーが クライアントアプリケーションを示すために使用する識別子に対応 SHOULDする。

両方の選択肢が可能である場合、リソースサーバーは クライアントのアイデンティティをリソース所有者のアイデンティティと誤認する可能性がある。 たとえば、クライアントが認可サーバーへの登録中に自身のclient_idを 選択できる場合、悪意あるクライアントはそれをリソース所有者を識別する値 (たとえばOpenID Connectが使用される場合のsub値)に設定する可能性がある。 リソースサーバーが、リソース所有者の関与によって取得されたアクセストークンと そうでないアクセストークンを適切に区別できない場合、クライアントは偶発的に リソース所有者に属するリソースへアクセスできる可能性がある。

この攻撃は、[RFC9068]を使用する実装だけでなく、 類似した独自ソリューションにも影響する可能性がある。

4.15.1. 対策

認可サーバーは、クライアントIDとユーザー識別子のための 共通名前空間が存在する場合、たとえば上記Section 4.15で示した [RFC9068]subクレーム例のような場合、 クライアントが自身のclient_idまたは本物のリソース所有者との混同を 引き起こし得るその他のクレームに影響を与えることを許可すべきでは SHOULD NOTない。これを回避できない場合、 認可サーバーは、リソースサーバーが2種類のアクセストークンを区別するための 他の手段を提供 MUSTしなければならない。

4.16. クリックジャッキング

Section 4.4.1.9 of [RFC6819]で説明されるように、 認可リクエストは、ユーザーインターフェイスリドレッシングとも呼ばれる クリックジャッキング攻撃を受けやすい。このような攻撃では、攻撃者は認可エンドポイントの ユーザーインターフェイスを無害な文脈に埋め込む。ユーザーはその文脈とやり取りしていると 信じて、たとえばボタンをクリックするが、実際には認可エンドポイントのユーザーインターフェイスと 意図せずやり取りする。逆のことも実現できる。すなわち、認可エンドポイントとやり取りしていると 信じているユーザーが、元のユーザーインターフェイスの上に重ねられた攻撃者提供の入力フィールドへ 意図せずパスワードを入力する場合である。クリックジャッキング攻撃は、たとえば 他の要素の上にほとんど見えないiframeを重ねることで、ユーザーが攻撃にほとんど気づけないように 設計できる。

攻撃者は、このベクトルを使用してユーザーの認証クレデンシャルを取得し、 クライアントに付与されるアクセスのスコープを変更し、場合によってはユーザーのリソースへアクセスできる。

認可サーバーはクリックジャッキング攻撃を防止 MUSTしなければならない。[RFC6819]では、 X-Frame-Options HTTPレスポンスヘッダーフィールドおよびframe-busting JavaScriptの使用を含む複数の対策が説明されている。それらに加えて、認可サーバーは Content Security Policy (CSP) level 2 [W3C.CSP-2]以上も使用 SHOULDする。

効果を発揮するためには、CSPは認可エンドポイント、および該当する場合には、 ユーザーを認証しクライアントを認可するために使用される他のエンドポイント (たとえばデバイス認可エンドポイント、ログインページ、エラーページなど)で使用されなければならない。 これにより、CSPをサポートするユーザーエージェントにおいて、許可されていないオリジンによる フレーミングが防止される。クライアントは、そのリダイレクトエンドポイントで使用されるものとは異なる 何らかのオリジンによってフレーム化されることを許可 MAYできる。このため、認可サーバーは、特定のクライアントについて 許可されたオリジンを管理者が設定できるようにし、および/またはクライアントがそれらを 動的に登録できるように SHOULDする。

CSPを使用すると、認可サーバーは単一のレスポンスヘッダーフィールドで 複数のオリジンを指定し、柔軟なパターンを用いてそれらを制約できる (詳細については[W3C.CSP-2]を参照)。 CSPのLevel 2は、frame-ancestorsを使用してフレームのオリジンを制限する ポリシーと、script-srcを使用してHTMLページ上で実行が許可されるスクリプトの ソースを制限するポリシーを組み合わせることにより、クリックジャッキングに対する 堅牢な保護機構を提供する。このようなポリシーの非規範的な例を次のリストに示す。

HTTP/1.1 200 OK
Content-Security-Policy: frame-ancestors https://ext.example.org:8000
Content-Security-Policy: script-src 'self'
X-Frame-Options: ALLOW-FROM https://ext.example.org:8000
...

一部のユーザーエージェントは[W3C.CSP-2]をサポートしないため、 そのようなレガシーユーザーエージェントが認可サーバーによって明示的にサポート外とされていない限り、 この技術は[RFC6819]で説明されるものを含む 他の技術と組み合わせる SHOULDである。そのような場合でも、追加の対策はなお採用される SHOULDである。

4.17. ブラウザー内 通信フローに対する攻撃

認可レスポンスがHTTPリダイレクトの代わりに postMessage [WHATWG.postmessage_api]のようなブラウザー内通信技術で 送信される場合、メッセージが意図せず悪意あるオリジンへ送信される、または 悪意あるオリジンから注入される可能性がある。

4.17.1.

ブラウザー内通信を使用する攻撃の次の非規範的な擬似コード例は、 [research.rub]で説明されている。

4.17.1.1. 受信者オリジンの不十分な制限

postMessageを介して認可レスポンスまたはトークンレスポンスを 送信する場合、認可サーバーはクライアントのオリジンではなくワイルドカードオリジン "*"へレスポンスを送信する。レスポンスが送信されるウィンドウが攻撃者に制御されている場合、 攻撃者はレスポンスを読み取ることができる。

window.opener.postMessage(
  {
    code: "ABC",
    state: "123"
  },
  "*" // any website in the opener window can receive the message
)
4.17.1.2. 不十分なURI検証

postMessageを介して認可レスポンスまたはトークンレスポンスを 送信する場合、認可サーバーは受信者オリジンをリダイレクトURIと照合しない可能性があり、 代わりに、たとえば攻撃者が提供したオリジンへレスポンスを送信する可能性がある。 これはSection 4.1で説明された攻撃に類似している。

window.opener.postMessage(
  {
    code: "ABC",
    state: "123"
  },
  "https://attacker.example" // attacker-provided value
)
4.17.1.3. 送信者オリジンの不十分な検証後の インジェクション

postMessageを介して認可レスポンスまたはトークンレスポンスを 期待するクライアントは、メッセージの送信者オリジンを検証しない可能性がある。 これにより、攻撃者が認可レスポンスまたはトークンレスポンスをクライアントへ 注入できる可能性がある。

悪意を持って注入された認可レスポンスの場合、 この攻撃はSection 4.7で説明されるCSRF攻撃の変種である。 Section 4.7で説明される対策は、この攻撃にも適用される。

悪意を持って注入されたトークンレスポンスの場合、 Section 4.10.1で説明される 送信者制約付きアクセストークンは、状況によっては攻撃を防止する可能性があるが、 一般にはSection 4.17.2で説明される 追加の対策が必要である。

4.17.2. 推奨事項

事前登録されたオリジンとクライアント受信者オリジンを比較する場合、 認可サーバーはSection 4.1.3で 説明される厳密な文字列照合を利用 MUSTしなければならない。 認可サーバーは、次の非規範的な例に示すように、信頼されたクライアント受信者オリジンへ postMessageを送信 MUSTしなければならない。

window.opener.postMessage(
  {
    code: "ABC",
    state: "123"
  },
  "https://client.example" // use explicit client origin
)

postMessage内の"*"のようなワイルドカードオリジンは使用しては MUST NOTならない。攻撃者がそれらを使用して、 被害者のブラウザー内メッセージを悪意あるオリジンへ漏えいさせることができるためである。 どちらの対策も、認可コードおよびアクセストークンの漏えい防止に寄与する (Section 4.1を参照)。

クライアントは、クライアント受信者エンドポイントにおける ブラウザー内メッセージの注入を防止 MUSTしなければならない。クライアントは、次の非規範的な例に示すように、 ブラウザー内メッセージの開始者オリジンを認可サーバーオリジンと比較するために、 厳密な文字列照合を利用 MUSTしなければならない。

window.addEventListener("message", (e) => {
  // validate exact authorization server origin
  if (e.origin === "https://honest.as.example") {
    // process e.data.code and e.data.state
  }
})

ブラウザー内通信フローは、異なる通信技術 (すなわちHTTPリダイレクトの代わりにpostMessage)を適用するだけであるため、 Section 2.1に列挙された認可レスポンスを保護するすべての対策は、 同様に適用され MUSTなければならない。

5. IANAに関する考慮事項

本文書にはIANAによる処置はない。

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

セキュリティに関する考慮事項は、Sections 23、および4で説明されている。

7. 参考文献

7.1. 規範的参考文献

[BCP195]
Best Current Practice 195、<https://www.rfc-editor.org/info/bcp195>
執筆時点で、このBCPは次のものから構成される。
Moriarty, K. and S. Farrell, "TLS 1.0およびTLS 1.1の非推奨化", BCP 195, RFC 8996, DOI 10.17487/RFC8996, , <https://www.rfc-editor.org/info/rfc8996>.
Sheffer, Y., Saint-Andre, P., and T. Fossati, "Transport Layer Security (TLS)およびDatagram Transport Layer Security (DTLS)の安全な使用に関する推奨事項", BCP 195, RFC 9325, DOI 10.17487/RFC9325, , <https://www.rfc-editor.org/info/rfc9325>.
[RFC3986]
Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): 汎用構文", STD 66, RFC 3986, DOI 10.17487/RFC3986, , <https://www.rfc-editor.org/info/rfc3986>.
[RFC6749]
Hardt, D., Ed., "OAuth 2.0認可 フレームワーク", RFC 6749, DOI 10.17487/RFC6749, , <https://www.rfc-editor.org/info/rfc6749>.
[RFC6750]
Jones, M. and D. Hardt, "OAuth 2.0認可フレームワーク: ベアラートークンの使用", RFC 6750, DOI 10.17487/RFC6750, , <https://www.rfc-editor.org/info/rfc6750>.
[RFC6819]
Lodderstedt, T., Ed., McGloin, M., and P. Hunt, "OAuth 2.0脅威モデルおよび セキュリティに関する考慮事項", RFC 6819, DOI 10.17487/RFC6819, , <https://www.rfc-editor.org/info/rfc6819>.
[RFC7521]
Campbell, B., Mortimore, C., Jones, M., and Y. Goland, "OAuth 2.0クライアント認証および認可 グラントのためのアサーションフレームワーク", RFC 7521, DOI 10.17487/RFC7521, , <https://www.rfc-editor.org/info/rfc7521>.
[RFC7523]
Jones, M., Campbell, B., and C. Mortimore, "OAuth 2.0クライアント認証 および認可グラントのためのJSON Web Token (JWT)プロファイル", RFC 7523, DOI 10.17487/RFC7523, , <https://www.rfc-editor.org/info/rfc7523>.
[RFC8252]
Denniss, W. and J. Bradley, "ネイティブアプリのためのOAuth 2.0", BCP 212, RFC 8252, DOI 10.17487/RFC8252, , <https://www.rfc-editor.org/info/rfc8252>.
[RFC8414]
Jones, M., Sakimura, N., and J. Bradley, "OAuth 2.0認可サーバー メタデータ", RFC 8414, DOI 10.17487/RFC8414, , <https://www.rfc-editor.org/info/rfc8414>.
[RFC8705]
Campbell, B., Bradley, J., Sakimura, N., and T. Lodderstedt, "OAuth 2.0相互TLSクライアント認証および証明書結合 アクセストークン", RFC 8705, DOI 10.17487/RFC8705, , <https://www.rfc-editor.org/info/rfc8705>.
[RFC9068]
Bertocci, V., "OAuth 2.0アクセストークンのための JSON Web Token (JWT)プロファイル", RFC 9068, DOI 10.17487/RFC9068, , <https://www.rfc-editor.org/info/rfc9068>.

7.2. 参考情報文献

[arXiv.1508.04324v2]
Mladenov, V., Mainka, C., and J. Schwenk, "現代のシングル サインオンプロトコルのセキュリティについて: OpenID Connectにおける二次脆弱性", arXiv:1508.04324v2, DOI 10.48550/arXiv.1508.04324, , <https://arxiv.org/abs/1508.04324v2/>.
[arXiv.1601.01229]
Fett, D., Küsters, R., and G. Schmitz, "OAuth 2.0の包括的な形式的 セキュリティ分析", arXiv:1601.01229, DOI 10.48550/arXiv.1601.01229, , <https://arxiv.org/abs/1601.01229/>.
[arXiv.1704.08539]
Fett, D., Küsters, R., and G. Schmitz, "Web SSO標準OpenID Connect: 詳細な形式的セキュリティ分析およびセキュリティガイドライン", arXiv:1704.08539, DOI 10.48550/arXiv.1704.08539, , <https://arxiv.org/abs/1704.08539/>.
[arXiv.1901.11520]
Fett, D., Hosseyni, P., and R. Küsters, "OpenID Financial-grade APIの広範な形式的 セキュリティ分析", arXiv:1901.11520, DOI 10.48550/arXiv.1901.11520, , <https://arxiv.org/abs/1901.11520/>.
[bug.chromium]
"New Tabを使用してリンクを開くとRefererヘッダーにURLフラグメントが含まれる", Chromium Issue Tracker, Issue ID: 40076763, <https://issues.chromium.org/issues/40076763>.
[JWT-ENCODED-STATE]
Bradley, J., Lodderstedt, T., and H. Zandbelt, "JWTを使用したOAuth 2 stateパラメーターへのクレームのエンコード", 作業中, Internet-Draft, draft-bradley-oauth-jwt-encoded-state-09, , <https://datatracker.ietf.org/doc/html/draft-bradley-oauth-jwt-encoded-state-09>.
[OAUTH-V2.1]
Hardt, D., Parecki, A., and T. Lodderstedt, "OAuth 2.1認可 フレームワーク", 作業中, Internet-Draft, draft-ietf-oauth-v2-1-12, , <https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12>.
[OAuth.Post]
Jones, M. and B. Campbell, "OAuth 2.0 Form Post Response Mode", The OpenID Foundation, , <https://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html>.
[OAuth.Responses]
de Medeiros, B., Ed., Scurtescu, M., Tarjan, P., and M. Jones, "OAuth 2.0 Multiple Response Type Encoding Practices", The OpenID Foundation, , <https://openid.net/specs/oauth-v2-multiple-response-types-1_0.html>.
[OpenID.Core]
Sakimura, N., Bradley, J., Jones, M., de Medeiros, B., and C. Mortimore, "OpenID Connect Core 1.0 incorporating errata set 2", The OpenID Foundation, , <https://openid.net/specs/openid-connect-core-1_0.html>.
[OpenID.Discovery]
Sakimura, N., Bradley, J., Jones, M., and E. Jay, "OpenID Connect Discovery 1.0 incorporating errata set 2", The OpenID Foundation, , <https://openid.net/specs/openid-connect-discovery-1_0.html>.
[OpenID.JARM]
Lodderstedt, T. and B. Campbell, "Financial-grade API: OAuth 2.0のためのJWT Secured Authorization Response Mode (JARM)", The OpenID Foundation, , <https://openid.net/specs/openid-financial-api-jarm.html>.
[owasp.redir]
OWASP Foundation, "検証されていないリダイレクトおよび フォワードのチートシート", OWASP Cheat Sheet Series, <https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html>.
[research.cmu]
Chen, E., Pei, Y., Chen, S., Tian, Y., Kotcher, R., and P. Tague, "モバイルアプリケーション開発者のためのOAuthの解明", CCS '14: Proceedings of the 2014 ACM SIGSAC Conference on Computer and Communications Security, pp. 892-903, DOI 10.1145/2660267.2660323, , <https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/OAuthDemystified.pdf>.
[research.jcs_14]
Bansal, C., Bhargavan, K., Delignat-Lavaud, A., and S. Maffeis, "形式的分析によるWebサイト認可に対する具体的攻撃の発見", Journal of Computer Security, vol. 22, no. 4, pp. 601-657, DOI 10.3233/JCS-140503, , <https://www.doc.ic.ac.uk/~maffeis/papers/jcs14.pdf>.
[research.rub]
Jannett, L., Mladenov, V., Mainka, C., and J. Schwenk, "DISTINCT: Dual-Window Single Sign-Onにおけるブラウザー内通信を使用した アイデンティティ窃取", CCS '22: Proceedings of the 2022 ACM SIGSAC Conference on Computer and Communications Security, DOI 10.1145/3548606.3560692, , <https://dl.acm.org/doi/pdf/10.1145/3548606.3560692>.
[research.rub2]
Fries, C., "実世界のOpenID Connect実装の セキュリティ分析", 修士論文, Ruhr-Universität Bochum (RUB), , <https://www.nds.rub.de/media/ei/arbeiten/2021/05/03/masterthesis.pdf>.
[research.ubc]
Sun, S.-T. and K. Beznosov, "悪魔は(実装)詳細に宿る: OAuth SSOシステムの実証的分析", Proceedings of the 2012 ACM conference on Computer and communications security (CCS '12), pp. 378-390, DOI 10.1145/2382196.2382238, , <https://css.csail.mit.edu/6.858/2012/readings/oauth-sso.pdf>.
[research.udel]
Liu, D., Hao, S., and H. Wang, "あなたのDNSレコードはすべて我々を指している: 宙ぶらりんDNSレコードのセキュリティ脅威の理解", CCS '16: Proceedings of the 2016 ACM SIGSAC Conference on Computer and Communications Security, pp. 1414-1425, DOI 10.1145/2976749.2978387, , <https://dl.acm.org/doi/pdf/10.1145/2976749.2978387>.
[RFC2119]
Bradner, S., "RFCにおいて 要件レベルを示すために使用されるキーワード", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/info/rfc2119>.
[RFC7591]
Richer, J., Ed., Jones, M., Bradley, J., Machulak, M., and P. Hunt, "OAuth 2.0動的クライアント登録 プロトコル", RFC 7591, DOI 10.17487/RFC7591, , <https://www.rfc-editor.org/info/rfc7591>.
[RFC7636]
Sakimura, N., Ed., Bradley, J., and N. Agarwal, "OAuthパブリッククライアントによる Proof Key for Code Exchange", RFC 7636, DOI 10.17487/RFC7636, , <https://www.rfc-editor.org/info/rfc7636>.
[RFC8174]
Leiba, B., "RFC 2119キーワードにおける大文字と 小文字の曖昧性", BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/info/rfc8174>.
[RFC8707]
Campbell, B., Bradley, J., and H. Tschofenig, "OAuth 2.0のためのリソースインジケーター", RFC 8707, DOI 10.17487/RFC8707, , <https://www.rfc-editor.org/info/rfc8707>.
[RFC9101]
Sakimura, N., Bradley, J., and M. Jones, "OAuth 2.0認可 フレームワーク: JWT保護認可リクエスト (JAR)", RFC 9101, DOI 10.17487/RFC9101, , <https://www.rfc-editor.org/info/rfc9101>.
[RFC9110]
Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP Semantics", STD 97, RFC 9110, DOI 10.17487/RFC9110, , <https://www.rfc-editor.org/info/rfc9110>.
[RFC9126]
Lodderstedt, T., Campbell, B., Sakimura, N., Tonge, D., and F. Skokan, "OAuth 2.0 Pushed Authorization Requests", RFC 9126, DOI 10.17487/RFC9126, , <https://www.rfc-editor.org/info/rfc9126>.
[RFC9207]
Meyer zu Selhausen, K. and D. Fett, "OAuth 2.0認可サーバー発行者識別", RFC 9207, DOI 10.17487/RFC9207, , <https://www.rfc-editor.org/info/rfc9207>.
[RFC9396]
Lodderstedt, T., Richer, J., and B. Campbell, "OAuth 2.0 Rich Authorization Requests", RFC 9396, DOI 10.17487/RFC9396, , <https://www.rfc-editor.org/info/rfc9396>.
[RFC9440]
Campbell, B. and M. Bishop, "Client-Cert HTTP Header Field", RFC 9440, DOI 10.17487/RFC9440, , <https://www.rfc-editor.org/info/rfc9440>.
[RFC9449]
Fett, D., Campbell, B., Bradley, J., Lodderstedt, T., Jones, M., and D. Waite, "OAuth 2.0 Demonstrating Proof of Possession (DPoP)", RFC 9449, DOI 10.17487/RFC9449, , <https://www.rfc-editor.org/info/rfc9449>.
[TOKEN-BINDING]
Jones, M., Campbell, B., Bradley, J., and W. Denniss, "OAuth 2.0 Token Binding", 作業中, Internet-Draft, draft-ietf-oauth-token-binding-08, , <https://datatracker.ietf.org/doc/html/draft-ietf-oauth-token-binding-08>.
[W3C.CSP-2]
West, M., Barth, A., and D. Veditz, "Content Security Policy Level 2", W3C勧告, , <https://www.w3.org/TR/2016/REC-CSP2-20161215/>. 最新版は<https://www.w3.org/TR/CSP2/>で入手可能。
[W3C.webappsec-referrer-policy]
Eisinger, J. and E. Stark, "Referrer Policy", , <https://www.w3.org/TR/2017/CR-referrer-policy-20170126/>. 最新版は<https://www.w3.org/TR/referrer-policy/>で入手可能。
[W3C.WebAuthn]
Hodges, J., Jones, J.C., Jones, M.B., Kumar, A., and E. Lundberg, "Web Authentication: An API for accessing Public Key Credentials Level 2", W3C 勧告, , <https://www.w3.org/TR/2021/REC-webauthn-2-20210408/>. 最新版は<https://www.w3.org/TR/webauthn-2/>で入手可能。
[W3C.WebCrypto]
Watson, M., Ed., "Web Cryptography API", W3C勧告, , <https://www.w3.org/TR/2017/REC-WebCryptoAPI-20170126/>. 最新版は<https://www.w3.org/TR/WebCryptoAPI/>で入手可能。
[WHATWG.CORS]
WHATWG, "CORS protocol", Fetch: Living Standard, Section 3.2, , <https://fetch.spec.whatwg.org/#http-cors-protocol>.
[WHATWG.postmessage_api]
WHATWG, "Cross-document messaging", HTML: Living Standard, Section 9.3, , <https://html.spec.whatwg.org/multipage/web-messaging.html#web-messaging>.

謝辞

貴重なフィードバックを寄せてくださった Brock Allen, Annabelle Richard Backman, Dominick Baier, Vittorio Bertocci, Brian Campbell, Bruno Crispo, William Dennis, George Fletcher, Matteo Golinelli, Dick Hardt, Joseph Heenan, Pedram Hosseyni, Phil Hunt, Tommaso Innocenti, Louis Jannett, Jared Jennings, Michael B. Jones, Engin Kirda, Konstantin Lapine, Neil Madden, Christian Mainka, Jim Manico, Nov Matake, Doug McDorman, Karsten Meyer zu Selhausen, Ali Mirheidari, Vladislav Mladenov, Kaan Onarioglu, Aaron Parecki, Michael Peck, Johan Peeters, Nat Sakimura, Guido Schmitz, Jörg Schwenk, Rifaat Shekh-Yusef, Travis Spencer, Petteri Stenius, Tomek Stojecki, David Waite, Tim Würtele, and Hans Zandbelt に感謝する。

著者連絡先

Torsten Lodderstedt
SPRIND
John Bradley
Yubico
Andrey Labunets
Independent Researcher
Daniel Fett
Authlete