| RFC 9700 | OAuth 2.0セキュリティBCP | 2025年1月 |
| Lodderstedtほか | ベストカレントプラクティス | [ページ] |
本文書は、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で入手できる。¶
Copyright (c) 2025 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.¶
[RFC6749] および[RFC6750]で公開されて以来、 OAuth 2.0(本文書では単に "OAuth" と呼ぶ)は市場で大きく普及し、API保護の標準となり、 OpenID Connect [OpenID.Core]を用いた フェデレーテッドログインの基盤となった。 OAuthはさまざまなシナリオおよび異なる種類のデプロイメントで使用されているが、 次のような課題が観察される。¶
OAuth実装は、既知の実装上の弱点やアンチパターン (すなわち、安全でないと見なされる既知のパターン)を通じて攻撃されている。 これらの脅威の大半はOAuth 2.0の 脅威モデルおよびセキュリティに関する考慮事項 [RFC6819]で論じられているが、継続的な悪用は、 より具体的な推奨事項、実装しやすい緩和策、および多層防御の必要性を示している。¶
OAuthは、当初想定されていたよりも高いセキュリティ要件を持つ環境、 たとえばオープンバンキング、eHealth、eGovernment、電子署名などで使用されている。 これらのユースケースでは、より厳格な指針と追加の保護が求められる。¶
OAuthは、当初想定されていたよりもはるかに動的な構成で使用されており、 セキュリティに関して新たな課題を生み出している。これらの課題は、 [RFC6749]、[RFC6750]、および[RFC6819]の当初の範囲を超えている。¶
OAuthは当初、クライアント、 認可サーバー、およびリソースサーバーの間の静的な関係を想定していた。 サーバーのURLはデプロイ時にクライアントに知られており、それらの当事者間の 信頼関係のアンカーを構成していた。クライアントが正当なサーバーと通信しているかどうかの 検証は、TLSサーバー認証に基づいていた(Section 4.5.4 of [RFC6819]を参照)。 OAuthの採用が拡大するにつれて、この単純なモデルは崩れ、いくつかの シナリオでは、一方のクライアントと、他方の特定のデプロイメントにおける 認可サーバーおよびリソースサーバーとの関係を動的に確立する方式に置き換えられた。 これにより、同じクライアントを、(メールやOpenID Connectなどの標準APIの場合に) 異なるプロバイダーのサービスにアクセスするために使用したり、マルチテナント環境における 特定のテナントへのフロントエンドとして機能させたりできるようになった。 OAuth 2.0 Dynamic Client Registration Protocol [RFC7591]およびOAuth 2.0 Authorization Server Metadata [RFC8414]などのOAuthの拡張は、 動的なシナリオでOAuthを使用することを支援するために開発された。¶
技術は変化した。たとえば、ブラウザーがリクエストをリダイレクトする際に フラグメントを扱う方法が変化し、それに伴ってインプリシットグラントの 基礎となるセキュリティモデルも変化した。¶
本文書は、これらの課題に対処するための更新されたセキュリティ推奨事項を提供する。 OAuth 2.0 [RFC6749]や OpenID Connect [OpenID.Core] などの既存仕様で定義されたものを超える新たな要件を導入し、 安全性が低い、または安全でないと見なされる一部の運用モードを非推奨とする。 ただし、本文書は [RFC6749]、[RFC6750]、および[RFC6819]で示されたセキュリティ上の助言に取って代わるものではなく、 それらの文書を補完するものである。¶
当然ながら、既存のすべてのエコシステムや実装が 新しい要件と互換性を持つわけではなく、本文書で説明されるベストプラクティスに従うことで 相互運用性が損なわれる可能性がある。それでもなお、実装者が 可能な限り速やかに実装およびエコシステムをアップグレードすることが RECOMMENDEDである。¶
[OAUTH-V2.1]として開発中のOAuth 2.1は、 本文書のセキュリティ推奨事項を取り込む予定である。¶
本文書の残りは次のように構成されている。Section 2では、 すべてのOAuth実装者にとって最も重要なベストプラクティスを要約する。 Section 3では、更新されたOAuth攻撃者 モデルを提示する。Section 4では、 (執筆時点で)実際に見られる脅威および実装上の問題について詳細に分析し、 潜在的な対策について論じる。¶
本文書におけるキーワード「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サーバー上のエンドポイントである。¶
本セクションでは、執筆時点でベストプラクティスと見なされる セキュリティ機構および対策の中核的な集合を説明する。 これらのセキュリティ機構および対策に関する詳細(詳細な攻撃の説明を含む)、 ならびにあまり一般的に使用されない選択肢に対する要件は、 Section 4で提供される。¶
事前登録された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¶
issパラメーターを使用する、または¶
iss値([OpenID.Core]におけるID Token内の
issクレーム、または[OpenID.JARM]レスポンス内のものなど)に基づく
代替対策を使用し、
その値を[RFC9207]で説明されるとおりに処理する。¶
これらの選択肢がない場合、クライアントは代わりに、 Section 4.4.2で説明されるように、 認可エンドポイントおよびトークンエンドポイントを識別するために個別のリダイレクトURIを使用 MAYできる。¶
ユーザークレデンシャルを含む可能性があるリクエストをリダイレクトする認可サーバーは、 これらのユーザークレデンシャルを誤って転送することを回避 MUSTである(詳細については Section 4.12を参照)。¶
クライアントは、次のいずれかの選択肢を用いて、認可コード インジェクション攻撃(Section 4.5を参照)および認可コードの悪用を防止 MUSTである。¶
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できる。¶
インプリシットグラント(レスポンスタイプtoken)および、
認可サーバーが認可レスポンス内でアクセストークンを発行することを引き起こす
その他のレスポンスタイプは、
Sections 4.1、
4.2、4.3、および
4.6で説明されるように、
アクセストークン漏えいおよび
アクセストークンリプレイに対して脆弱である。¶
さらに、アクセストークンが 認可レスポンス内で発行される場合、(Section 2.2で 推奨されるように)アクセストークンを特定のクライアントに結び付けるための 送信者制約を行う標準化された方法は存在しない。 これは、攻撃者が漏えいまたは盗難されたアクセストークンをリソースエンドポイントで使用できることを意味する。¶
これらの問題を避けるため、クライアントは、
認可レスポンス内でのアクセストークン注入が防止され、前述のトークン漏えい
ベクトルが緩和されていない限り、インプリシット
グラント(レスポンスタイプtoken)または認可レスポンス内で
アクセストークンを発行するその他のレスポンスタイプを使用すべきでは
SHOULD NOTない。¶
クライアントは代わりに、
Section 2.1.1で規定されるレスポンス
タイプcode(すなわち、認可
コードグラントタイプ)、またはcode id_tokenレスポンスタイプのように
認可サーバーがトークンレスポンス内でアクセストークンを発行することを引き起こす
その他のレスポンスタイプを使用
SHOULDである。これにより、
認可サーバーは攻撃者によるリプレイ試行を検出でき、
アクセストークンがURLに露出しないため、一般に攻撃対象領域が削減される。
また、認可サーバーが発行されたトークンに
送信者制約を付けることも可能になる(Section
2.2を参照)。¶
送信者制約付きアクセストークンは、 アクセス トークンの適用範囲を特定の送信者に限定する。この送信者は、 そのトークンが受信者(たとえばリソースサーバー)で受け入れられる前提条件として、 特定の秘密を知っていることを示す義務を負う。¶
認可サーバーおよびリソースサーバーは、 盗まれた、または漏えいしたアクセストークンの悪用を防止するために、 OAuth 2.0の相互TLS [RFC8705]またはOAuth 2.0 Demonstrating Proof of Possession (DPoP) [RFC9449](Section 4.10.1を参照) など、アクセストークンに送信者制約を付ける仕組みを使用 SHOULDである。¶
パブリッククライアント向けのリフレッシュトークンは、 送信者制約付きであるか、Section 4.14で説明されるリフレッシュ トークンローテーションを使用 MUSTである。[RFC6749]はすでに、 コンフィデンシャルクライアント向けのリフレッシュトークンは、それが発行された クライアントによってのみ使用できることを義務付けている。¶
アクセストークンに関連付けられる権限は、 特定のアプリケーションまたはユースケースに必要な最小限に制限 SHOULDされる。これにより、 クライアントがリソース所有者によって認可された権限を超えることを防ぐ。 また、ユーザーがそれぞれのセキュリティポリシーによって認可された権限を 超えることも防ぐ。権限制限は、 アクセストークン漏えいの影響を低減するのにも役立つ。¶
特に、アクセストークンは、
特定のリソースサーバー、またはそれが実現できない場合には少数のリソースサーバーに対して
オーディエンス制限
SHOULDされる。これを実施するために、
認可サーバーはアクセストークンを特定のリソースサーバーに関連付け、
各リソースサーバーは、すべてのリクエストについて、そのリクエストとともに送信された
アクセストークンが当該リソースサーバーで使用されることを意図したものかどうかを検証する義務を負う。
意図されたものでない場合、リソースサーバーは当該リクエストの処理を拒否
MUSTである。
[RFC9068]で定義されるaudクレームは、
アクセストークンをオーディエンス制限するために使用
MAYできる。クライアントおよび認可サーバーは、
アクセスしたいリソースサーバーを決定するために、それぞれ[RFC6749]および
[RFC8707]で規定される
scopeまたはresourceパラメーターを利用
MAYできる。¶
さらに、アクセストークンは、
リソースサーバー上の特定のリソースおよびアクション、またはリソースに制限
SHOULDされる。これを実施するために、
認可サーバーはアクセストークンを対応するリソースおよびアクションに関連付け、
各リソースサーバーは、すべてのリクエストについて、そのリクエストとともに送信された
アクセストークンが当該リソースに対する当該アクションに使用されることを
意図したものかどうかを検証する義務を負う。
意図されたものでない場合、リソースサーバーは当該リクエストの処理を拒否しなければならない。
クライアントおよび認可サーバーは、
これらのリソースおよび/またはアクションを決定するために、
[RFC6749]で規定される
scopeパラメーターおよび[RFC9396]で
規定されるauthorization_detailsを利用
MAYできる。¶
リソース所有者パスワードクレデンシャルグラント [RFC6749]は使用しては MUST NOTならない。このグラントタイプは、リソース 所有者のクレデンシャルをクライアントに安全でない形で露出する。 クライアントが善意であっても、このグラントを使用すると攻撃対象領域が増加し (すなわち、クレデンシャルが認可サーバー以外の場所でも漏えいする可能性がある)、 ユーザーに対して認可サーバー以外の場所にクレデンシャルを入力する習慣を身につけさせることになる。¶
さらに、リソース所有者パスワードクレデンシャルグラントは、 二要素認証や、複数のユーザー操作ステップを必要とする認証プロセスと連携するようには設計されていない。 暗号クレデンシャルによる認証 (WebCrypto [W3C.WebCrypto]、 WebAuthn [W3C.WebAuthn]を参照)は、 通常は特定のWebオリジンに結び付けられているため、このグラントタイプで実装することは 不可能な場合がある。¶
認可サーバーは、特定のデプロイメントにおいて、 クライアント向けのクレデンシャルの発行/登録プロセスを確立し、 それらのクレデンシャルの機密性を保証することが可能である場合、 クライアント認証を強制 SHOULDである。¶
クライアント認証には、OAuth 2.0の相互TLS
[RFC8705]や、
[RFC7521]および
[RFC7523]に従った署名付きJWT
("Private Key JWT")など、非対称暗号を使用することが
RECOMMENDEDである。後者は
[OpenID.Core]において
クライアント認証方式private_key_jwtとして定義されている。
クライアント認証に非対称暗号を使用する場合、認可
サーバーは機密性の高い対称鍵を保存する必要がないため、
これらの方式は鍵の漏えいに対してより堅牢になる。¶
OAuth Authorization Server Metadata [RFC8414]の使用は、 OAuthデプロイメントのセキュリティ向上に役立つ。¶
したがって、認可 サーバーが[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ならない。クライアントはこのエンドポイントに直接アクセスせず、
代わりにユーザーエージェントをそこへリダイレクトするためである。¶
[RFC6819]では、 OAuthデプロイメントが保護されなければならない脅威を記述する脅威モデルが示されている。 その際、[RFC6819]は、攻撃者とその能力について一定の仮定を置いている。 すなわち、暗黙のうちに攻撃者モデルを確立している。以下では、この攻撃者モデルを 明示し、(Section 1で説明したような)複数の当事者を含む潜在的に動的な 関係を考慮し、新しい種類の攻撃者を含め、攻撃者モデルをより明確に定義するために、 更新および拡張する。¶
本文書の目的は、認可サーバーにおけるリソース所有者 (ユーザーエージェントを伴う)の認可と、その後のリソースサーバーにおける アクセストークンの使用が、少なくとも次の攻撃者に対して、 実用上可能な限り保護されることを保証することである。¶
ブラウザーやサーバーを含む任意の数の ネットワークエンドポイント(「正直な」ものを除く)を設定し運用できる Web攻撃者。Web攻撃者は、リソース所有者が訪問するWebサイトを設定し、 自身のユーザーエージェントを運用し、プロトコルに参加することができる。¶
特に、Web攻撃者は、認可サーバーに登録された OAuthクライアントを運用でき、また、リソース所有者や他のリソース所有者が (「正直な」ものと並行して)使用できる、自身の認可サーバーおよび リソースサーバーを運用できる。¶
また、Web攻撃者は任意の時点で、攻撃者が選んだ任意のURIへ ユーザーのブラウザーを誘導できると仮定しなければならない。実際には、これは 広告ネットワークに悪意ある広告を注入する、正当らしく見えるメールを送信するなど、 多くの方法で実現できる。¶
Web攻撃者は、自身のユーザークレデンシャルおよび 以前に知り得た任意の秘密を使用して、新しいメッセージを作成できる。 たとえば、Web攻撃者が設定ミスのあるリダイレクトURIを通じて ユーザーの認可コードを知った場合、そのWeb攻撃者はそのコードを アクセストークンと交換しようとすることができる。¶
しかし、攻撃者を対象としていないメッセージ (たとえば、攻撃者の制御下にない認可サーバーのURLへ送信されたもの)を 読み取ったり操作したりすることはできない。¶
さらに、プロトコル参加者が通信するネットワークを 完全に制御できるネットワーク攻撃者。これらの攻撃者は、 メッセージが暗号方式(たとえばTLS)によって適切に保護されている場合を除き、 メッセージを盗聴、操作、および偽装できる。 ネットワーク攻撃者は任意のメッセージをブロックすることもできる。¶
Web攻撃者の例としてはインターネットサービスプロバイダーの顧客が考えられ、 ネットワーク攻撃者としては、インターネットサービスプロバイダー自体、 ARPスプーフィングを用いる公共(Wi-Fi)ネットワーク上の攻撃者、または インターネットエクスチェンジポイントへアクセスできる国家支援攻撃者などが考えられる。¶
前述の攻撃者(A1)および (A2)は、OAuthの形式的解析 [arXiv.1601.01229]で使用された攻撃者モデルに適合する。 これは最小限の攻撃者モデルである。 実装者は、自身のOAuth実装の環境において考えられるすべての種類の攻撃者を考慮 MUSTしなければならない。たとえば、[arXiv.1901.11520]では、 トークンエンドポイントを完全に制御する攻撃者を含む、非常に強力な攻撃者モデルが使用されている。 これは、エコシステム内のエンドポイント設定ミスの影響をモデル化しているが、 Section 2.6で説明した認可サーバーメタデータを使用することで回避できる。 したがって、このような攻撃者はここには列挙していない。¶
しかし、OAuthに対する過去の攻撃は、次の種類の攻撃者が 特に関連することを示している。¶
認可レスポンスの内容を読み取ることはできるが、変更することはできない攻撃者 (すなわち、認可レスポンスが攻撃者に漏えいする可能性がある)。¶
このような攻撃の例には、オープンリダイレクター攻撃や Mix-Up攻撃(Section 4.4を参照)が含まれる。 これらでは、クライアントが攻撃者の制御する認可サーバーへ クレデンシャルを送信するようにだまされる。¶
また、次のものを悪用する攻撃も含まれる。¶
認可リクエストの内容を読み取ることはできるが、 変更することはできない攻撃者(すなわち、認可リクエストが上記と同様の方法で 攻撃者に漏えいする可能性がある)。¶
認可サーバーによって発行されたアクセストークンを取得できる攻撃者。 たとえば、リソースサーバーが攻撃者に侵害される、設定ミスにより アクセストークンが攻撃者の制御するリソースサーバーへ送信される、または ソーシャルエンジニアリングによってリソース所有者に攻撃者の制御する リソースサーバーを使用させることがあり得る。Section 4.9.2も参照。¶
(A3)、(A4)、および(A5)は、 通常、(A1)または(A2)のいずれかと共に発生する。 攻撃者は共通の目標に到達するために協力できる。¶
攻撃者(A1)または(A2)は、リソース所有者であることも、 リソース所有者として振る舞うこともできる点に注意すること。たとえば、そのような攻撃者は、 自身のブラウザーを使用して、上記のいずれかの攻撃で取得したトークンまたは認可コードを クライアントまたはリソースサーバーでリプレイできる。¶
本セクションでは、OAuth実装に対する攻撃について、 潜在的な対策とともに詳細に説明する。[RFC6819]で すでに扱われている攻撃および緩和策は、新しい推奨事項が示される場合を除き、ここには列挙しない。¶
本セクションではさらに、特定のケースおよびプロトコルオプションについて、 (Section 2で定義されたものを超える) 追加要件を定義する。¶
一部の認可サーバーは、完全なリダイレクトURIの代わりに、 クライアントがリダイレクトURIパターンを登録することを許可している。 認可サーバーはその後、実行時に認可エンドポイントでリダイレクトURIパラメーター値を 登録済みパターンと照合する。このアプローチにより、クライアントは トランザクション状態を追加のリダイレクトURIパラメーターにエンコードしたり、 複数のリダイレクトURIのために単一のパターンを登録したりできる。¶
このアプローチは、厳密なリダイレクトURI照合よりも 実装が複雑で、管理時に誤りを起こしやすいことが判明した。 パターン照合実装または具体的な設定の欠陥を悪用する成功した攻撃が、 実際に複数観察されている(たとえば[research.rub2]を参照)。 リダイレクト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を用いて、 認可エンドポイントに対する次の認可リクエストを開始する(改行は表示のためのみ)。¶
認可サーバーはリダイレクト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として登録することで)
それを乗っ取れる可能性がある。¶
上記の攻撃はインプリシットグラントでも機能する。 攻撃者が認可レスポンスを攻撃者の制御する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を使用する
(改行は表示のためのみ)。¶
すると、リダイレクトURIが登録済みパターンと一致するため、 認可サーバーはリクエストを許可し、結果のアクセストークンを303リダイレクトで送信する (一部のレスポンスパラメーターは読みやすさのため省略)。¶
client.somesite.exampleでは、リクエストはオープンリダイレクターに到達する。
エンドポイントはredirectパラメーターを読み取り、URL
https://attacker.example/へのHTTP 303 Locationヘッダーリダイレクトを発行する。¶
client.somesite.exampleのリダイレクターは
Locationヘッダーにフラグメントを含めないため、ユーザーエージェントは元のフラグメント
#access_token=2YotnFZFEjr1zCsicMWpAA&...をURLへ再付加し、
次のURLへ移動する。¶
https://attacker.example/#access_token=2YotnFZFEjr1z...¶
その後、attacker.exampleの攻撃者のページは
フラグメントにアクセスし、アクセストークンを取得できる。¶
パターン照合を正しく実装および管理する複雑さは、
明らかにセキュリティ問題を引き起こす。したがって、本文書は、
厳密なリダイレクトURI照合を使用することで、必要なロジックおよび設定を
単純化することを助言する。これは、認可サーバーが2つのURIが等しいことを保証
MUSTしなければならないことを意味する。
詳細については、Section 6.2.1 of [RFC3986]のSimple String Comparisonを参照。
唯一の例外は、localhost URIを使用するネイティブアプリである。この場合、
認可サーバーはSection
7.3 of [RFC8252]で説明されるように、
可変ポート番号を許可
MUSTしなければならない。¶
追加の推奨事項。¶
#_を付加することで、ブラウザーがフラグメントを
リダイレクトURLへ再付加することを防止
MAYできる。¶
リダイレクトURIを含む認可リクエストの起源および完全性を検証できる場合、 たとえばクライアント認証とともに [RFC9101]または[RFC9126]を使用する場合、 認可サーバーは追加の検査なしにリダイレクトURIを信頼 MAYできる。¶
認可リクエストURIまたは認可レスポンスURIの内容は、
それぞれ認可サーバーまたはクライアントのWebサイトから漏れることにより、
Referer HTTPヘッダー(Section 10.1.3 of [RFC9110]を参照)を通じて、意図せず攻撃者に開示される可能性がある。
最も重要な点として、認可コードまたはstate値がこの方法で開示され得る。
Section
10.1.3 of [RFC9110]では別途規定されているものの、
Chromiumプロジェクトの(現在は修正済みの)問題
[bug.chromium]で例示されるように、
ブラウザー実装の問題により、URIフラグメントで運ばれるアクセストークンにも同じことが起こり得る。¶
OAuthクライアントからの漏えいは、成功した認可リクエストの結果として、 クライアントが次のようなページをレンダリングすることを必要とする。¶
ブラウザーが攻撃者のページへ移動する、またはサードパーティコンテンツを読み込むとすぐに、
攻撃者は認可レスポンスURLを受け取り、codeまたはstate
(場合によってはaccess_token)を抽出できる。¶
Refererヘッダーを通じて有効なコードまたはアクセストークンを知った攻撃者は、
Sections 4.1.1、
4.5、および
4.6で説明される攻撃を実行できる。
攻撃者がstateを知った場合、stateを使用して得られるCSRF保護は失われ、
Section
4.4.1.8 of [RFC6819]で説明される
CSRF攻撃につながる。¶
OAuth認可レスポンスの結果としてレンダリングされるページおよび 認可エンドポイントは、サードパーティリソースまたは外部サイトへのリンクを含めるべきでは SHOULD NOTない。¶
次の対策は、攻撃が成功する可能性をさらに低減する。¶
Referrer-Policy:
no-referrerは、結果の文書から発生するすべてのリクエストにおいて
Refererヘッダーを完全に抑止する。¶
Section 4.1.2 of [RFC6749]で説明されるように、 認可コードはトークンエンドポイントで最初に使用された後、認可サーバーによって無効化され MUSTる。たとえば、認可サーバーが正当なクライアントによる引き換え後に コードを無効化した場合、攻撃者は後でこのコードを交換できない。¶
これは、攻撃者が正当なクライアントより先に コードをトークンと交換できた場合には攻撃を緩和しない。したがって、 [RFC6749]はさらに、 コードを二度引き換えようとする試みが行われた場合、認可サーバーは そのコードに基づいて以前に発行されたすべてのトークンを失効 SHOULDさせることを推奨している。¶
state値は、リダイレクトエンドポイントで
最初に使用された後にクライアントによって無効化される
SHOULDである。これが実装されており、
攻撃者がクライアントのWebサイトからRefererヘッダーを通じてトークンを受け取った場合、
stateはすでに使用済みで、クライアントによって無効化されており、
攻撃者が再び使用することはできない。(これは、stateが
認可サーバーのWebサイトから漏れた場合には役に立たない。その場合、stateはまだ
クライアントのリダイレクトエンドポイントで使用されていないためである。)¶
認可レスポンスには、リダイレクトの代わりに form postレスポンスモードを使用する([OAuth.Post]を参照)。¶
認可コードおよびアクセストークンは、ブラウザーの 訪問済みURL履歴に残る可能性があり、以下で説明する攻撃を可能にする。¶
すでにトークンを持つクライアントまたはWebサイトが、
provider.com/get_user_profile?access_token=abcdefのようなページへ
意図的に移動する場合、アクセストークンがブラウザー履歴に残る可能性がある。
[RFC6750]はこの慣行を推奨せず、
トークンをヘッダー経由で転送するよう助言しているが、実際にはWebサイトが
クエリパラメーターでアクセストークンを渡すことがよくある。¶
インプリシットグラントの場合、プロバイダーの
認可エンドポイントからのリダイレクトの結果として、
client.example/redirection_endpoint#access_token=abcdefのようなURLも
ブラウザー履歴に残る可能性がある。¶
対策。¶
Mix-Up攻撃は、OAuthクライアントが2つ以上の認可サーバーとやり取りし、 少なくとも1つの認可サーバーが攻撃者の制御下にあるシナリオで発生し得る。 たとえば、攻撃者が動的登録を使用して自身の認可サーバーにクライアントを登録する場合、 または認可サーバーが侵害される場合がこれに該当する。¶
攻撃の目的は、侵害されていない認可サーバーに対する認可コードまたは アクセストークンを取得することである。これは、クライアントをだまして、 それらのクレデンシャルを、侵害されていない認可/リソースサーバーの 対応するエンドポイントで使用させる代わりに、侵害された認可サーバー (攻撃者)へ送信させることで達成される。¶
ここでの説明は[arXiv.1601.01229]に従っており、 攻撃の変種を以下に概説する。¶
前提条件: この攻撃の変種が機能するには、次を仮定する。¶
以下ではさらに、クライアントがH-AS
(URI: https://honest.as.example、クライアントID:
7ZGZldHQ)およびA-AS(URI:
https://attacker.example、クライアントID: 666RVZJTA)に
登録されていると仮定する。以下の例で示すURLは、攻撃に関連するパラメーターのみを含むように
表示のため短縮されている。¶
認可コードグラントに対する攻撃。¶
https://attacker.example/authorize?response_type=code&client_id=666RVZJTAを
含むLocationヘッダーで、ユーザーをA-ASの認可エンドポイントへリダイレクトする。¶
https://honest.as.example/authorize?response_type=code&client_id=7ZGZldHQを
指すLocationヘッダーを持つリダイレクト(303 See Other)を受け取る。¶
ユーザーは、H-ASにおける自身のリソースへ クライアントがアクセスすることを認可する。(注意深いユーザーはこの時点で、 A-ASではなくH-ASを使用していることを意図に反していると検出できる可能性がある。 最初に列挙した攻撃の変種にはこの制限はない。)H-ASはコードを発行し、 (ブラウザー経由で)それをクライアントへ送り返す。¶
クライアントは、そのコードがA-ASによって発行されたものと 依然として仮定しているため、A-ASのトークンエンドポイントでコードを引き換えようとする。¶
したがって、攻撃者はコードを取得し、 (パブリッククライアントの場合)コードをアクセストークンと交換するか、 Section 4.5で説明される 認可コードインジェクション攻撃を実行できる。¶
変種。¶
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として宣言しつつ、 自身の制御下にあるトークンエンドポイントを宣言する可能性がある。¶
この防御は、認可サーバーがその発行者識別子を 認可レスポンスでクライアントへ送信することを要求する。 認可レスポンスを受信したとき、クライアントは受信した発行者識別子を 保存済みの発行者識別子と比較 MUSTしなければならない。不一致がある場合、クライアントは やり取りを中止 MUSTしなければならない。¶
この発行者識別子をクライアントへ伝送する方法はいくつかある。¶
issを介して伝送できる。¶
issクレームを評価できる。¶
どちらの場合も、iss値は
[RFC9207]に従って評価
MUSTされる。¶
この防御は、発行者情報を伝送するための新しいOAuth機能の デプロイを必要とする可能性があるが、Mix-Upに対する堅牢で比較的単純な防御である。¶
この防御では、クライアントは、やり取りする各発行者について 個別のリダイレクトURIを使用 MUSTしなければならない。¶
クライアントは、発行者のための個別のリダイレクトURIと、 認可レスポンスが受信されたURIとを比較することで、認可レスポンスが正しい 発行者から受信されたことを検査 MUSTしなければならない。不一致がある場合、クライアントは フローを中止 MUSTしなければならない。¶
この防御は既存のOAuth機能に基づいているが、 (一部のオープンバンキングスキームのように)多くの異なる発行者の使用のために クライアントが一度だけ登録するシナリオでは使用できず、クライアント登録との密な統合のため、 自動的にデプロイすることがより困難である。¶
さらに、攻撃者は、この防御が提供する保護を回避できる可能性がある。 すなわち、クライアントが攻撃者の認可サーバーに割り当てたリダイレクトURIを使用して、 「正直な」認可サーバーに新しいクライアントを登録することである。 その後、攻撃者は上記のように攻撃を実行し、クライアントIDを新しく作成した クライアントのクライアントIDへ置き換えることができる。¶
したがって、この防御は、他の選択肢が利用できない場合にのみ 使用される SHOULDである。¶
認可レスポンスに含まれる認可コードへアクセスできるようになった攻撃者 (Section 3の 攻撃者(A3)を参照)は、 認可コードをアクセストークンと交換しようとしたり、その他の方法で 認可コードを利用しようとしたりできる。¶
認可コードがパブリッククライアント用に作成された場合、 攻撃者は認可コードを認可サーバーのトークンエンドポイントへ送信し、 それによってアクセストークンを取得できる。この攻撃は Section 4.4.1.1 of [RFC6819]で説明されている。¶
コンフィデンシャルクライアントの場合、または一部の特殊な状況では、 攻撃者は以下で説明するように認可コードインジェクション攻撃を実行できる。¶
認可コードインジェクション攻撃では、攻撃者は盗まれた認可コードを クライアントにおける攻撃者自身のセッションへ注入しようとする。 その目的は、クライアントにおける攻撃者のセッションを被害者のリソースまたは アイデンティティに関連付け、それによって攻撃者に少なくとも限定的な 被害者のリソースへのアクセスを与えることである。¶
コンフィデンシャルクライアントのクライアント認証を回避することのほか、 この攻撃のユースケースには次のものが含まれる。¶
これらの特殊なケースを除き、コードがパブリッククライアント用に 作成されている場合、認可コードインジェクションは通常あまり魅力的ではない。 上記で説明したように、コードをトークンエンドポイントへ送信する方がより単純で強力な攻撃であるためである。¶
認可コードインジェクション攻撃は次のように機能する。¶
redirect_uriおよび
クライアントのクライアントIDとクライアントシークレット(または他のクライアント認証手段)とともに、
コードを認可サーバーのトークンエンドポイントへ送信する。¶
明らかに、コードが別のクライアント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照合を強制するという考えと衝突する。さらに、
プロバイダーがこの段階でredirect_uri検査要件を無視することが非常に多いことが
観察されている。おそらく、仕様を読む限りそれがセキュリティ上重要であるように
見えないためである。¶
他のプロバイダーは、redirect_uriパラメーターを
登録済みリダイレクトURIパターンと単にパターン照合するだけである。
これにより、認可サーバーは、各トランザクションについて実際のリダイレクトURIと
対応する認可コードとのリンクを保存する必要がなくなる。しかし、この種の検査は、
改ざん済みリダイレクトURIが考慮されないため、仕様の意図を明らかに満たしていない。
したがって、正当なクライアントのclient_idを使用して、または別のデバイス上で
正当なクライアントを利用して取得された認可コードを注入しようとする試みは、
それぞれのデプロイメントで検出されない。¶
Section 4.1.3 of [RFC6749]で定義される要件は、 クライアントがトークンエンドポイント呼び出しのために正しいリダイレクトURIを 保存または再構築する必要があるため、クライアント実装の複雑さを高めるとも想定される。¶
クライアント認証のための非対称方式は、この攻撃を止めない。 正当なクライアントがトークンエンドポイントで認証するためである。¶
したがって、本文書は代わりに、次に説明する機構のいずれかを使用し、 特定のトランザクションの文脈において、各認可コードを特定のデバイス上の (または特定のユーザーエージェント内の)特定のクライアントインスタンスに 結び付けることを推奨する。¶
認可コードをクライアントインスタンスに結び付けるには、 次の2つの優れた技術的解決策がある。¶
[RFC7636]で規定されるPKCE機構は、
(もともとはネイティブアプリを保護するために設計されたものの)対策として使用できる。
攻撃者が認可コードを注入しようとすると、code_verifierの検査は失敗する。
クライアントは自身の正しいverifierを使用するが、そのコードはこのverifierと一致しない
code_challengeに関連付けられているためである。¶
PKCEは認可コードインジェクション攻撃を防ぐだけでなく、
パブリッククライアント用に作成された認可コードも保護する。PKCEは、
攻撃者がcode_verifierを知らずに、認可サーバーのトークンエンドポイントで
盗まれた認可コードを引き換えられないことを保証する。¶
OpenID Connectの既存のnonceパラメーターは、
認可コードインジェクション攻撃から保護できる。nonce値は一回限り使用であり、
クライアントによって作成される。クライアントはそれをユーザーエージェントセッションに
結び付け、OpenID Provider (OP)への初期リクエストとともに送信することになっている。
OPは受信したnonce値を、トークンエンドポイントでのコード交換の一部として
発行されるID Tokenに入れる。
攻撃者が認可レスポンスに
認可コードを注入した場合、クライアントセッション内のnonce値と、トークンエンドポイントから
受信したID Token内のnonce値は一致せず、攻撃は検出される。
この仮定は、攻撃者が(対応する認可コードを盗んだ)被害者のデバイス上の
ユーザーエージェント状態を取得できないというものである。¶
この対策は、クライアントがトークンエンドポイントから取得した
ID Token内のnonceパラメーターを適切に検査し、その検査が成功するまで
発行されたトークンを一切使用しない場合にのみ機能する点に注意することが重要である。
より正確には、nonceパラメーターを用いてコードインジェクションから自身を保護する
クライアントは、次を行う。¶
nonceを検証
MUSTしなければならない。
これは、別のID Tokenが認可レスポンスから取得されていた場合
(たとえばresponse_type=code+id_token)でも同様である。および¶
nonceはパブリッククライアントの
認可コードを保護しない点に注意することが重要である。
攻撃者は認可コードインジェクション攻撃を実行する必要がないためである。
代わりに、攻撃者は盗まれた認可コードを用いてトークンエンドポイントを直接呼び出すことができる。¶
攻撃者が、被害者の認可リクエストで使用されるnonce値または
code_challenge値を変更できる場合、上記の対策を回避できる。
攻撃者は、これらの値を、上記攻撃のStep 2で
自身のセッションにおいてクライアントが選んだものと同じ値へ変更できる。
(これは、被害者のクライアントとのセッションが、攻撃者がクライアントとのセッションを
開始した後に始まることを必要とする。)その後、攻撃者が被害者から認可コードを
捕捉できる場合、PKCEまたはnonceが使用されていても、攻撃者は
Step
3で盗まれたコードを注入できる。¶
この攻撃は複雑であり、攻撃者と被害者のセッションの間に 密接な相互作用を必要とする。それにもかかわらず、認可レスポンスの内容を 攻撃者が読み取ることを防ぐための対策は、Sections 4.1、4.2、 4.3、4.4、および4.11で説明されるように、なお講じる必要がある。¶
アクセストークンインジェクション攻撃では、攻撃者は盗まれた アクセストークンを(攻撃者の制御下にない)正当なクライアントへ注入しようとする。 これは通常、攻撃者が漏えいしたアクセストークンを利用して、特定のクライアントで ユーザーになりすましたい場合に発生する。¶
攻撃を実行するために、攻撃者はインプリシットグラントを使用して
クライアントとのOAuthフローを開始し、認可サーバーが発行したアクセストークンを
置き換えることで認可レスポンスを変更するか、漏えいしたアクセストークンを含む
認可サーバーレスポンスを直接作り上げる。レスポンスには、この特定のトランザクションのために
クライアントが生成したstate値が含まれるため、クライアントはそのレスポンスを
CSRF攻撃として扱わず、攻撃者が注入したアクセストークンを使用する。¶
純粋なOAuthフローでは、このようなインジェクション攻撃を検出する方法はない。 トークンがトランザクションまたは特定のユーザーエージェントへの結び付けなしに 発行されるためである。¶
OpenID Connectでは、認可レスポンスにat_hashクレームを
含むID Tokenが追加で含まれるため、この攻撃を緩和できる。したがって、攻撃者は
レスポンス内のアクセストークンとID Tokenの両方を置き換える必要がある。
ID Tokenは認証を伴って署名または暗号化されているため、攻撃者はID Tokenを偽造できない。
また、漏えいしたID Token内のnonceクレームは、認可レスポンスで期待される値とは
(非常に高い確率で)異なる値を含むため、攻撃者は盗まれたアクセストークンに一致する
漏えいID Tokenを注入することもできない。¶
攻撃者がアクセストークンをリソースエンドポイントで直接使用することを防ぐには、 送信者制約付きアクセストークンのような追加の保護がなお必要である点に注意すること。¶
Section 2.1.2の推奨事項はこれに由来する。¶
攻撃者は、被害者のデバイス上の正当なクライアントの リダイレクトURIへリクエストを注入しようとする可能性がある。たとえば、 クライアントに攻撃者の制御下にあるリソースへアクセスさせるためである。 これはCross-Site Request Forgery (CSRF)として知られる攻撃の変種である。¶
長く確立された対策は、クライアントが
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攻撃に使用できる。¶
PKCEをサポートしているものの、すべてのフローでその使用を必須としていない 認可サーバーは、PKCEダウングレード攻撃を受けやすい可能性がある。¶
この攻撃の第一の前提条件は、特定のフローについてPKCEを有効化または
無効化する、攻撃者が制御可能なフラグが認可リクエスト内に存在することである。
code_challengeパラメーターの存在または不在はこの目的に適している。
すなわち、このパラメーターが認可リクエストに存在する場合、認可サーバーは
PKCEを有効化し強制するが、パラメーターが欠落している場合にはPKCEを強制しない。¶
この攻撃の第二の前提条件は、クライアントがstateをまったく
使用していないこと(たとえば、クライアントがCSRF防止にPKCEへ依存しているため)、
またはクライアントがstateを正しく検査していないことである。¶
大まかに言えば、この攻撃はCSRF攻撃の変種である。 攻撃者は、Section 4.7で説明された攻撃と同じ目標を達成する。 すなわち、攻撃者は、攻撃者のリソースに結び付いた認可コード (そしてそれによりアクセストークン)を、被害者とクライアントの間のセッションへ注入する。¶
code_challenge=hash(abc)パラメーターを設定している
(ハッシュ関数およびパラメーターエンコーディングは[RFC7636]で定義されるとおり)。
クライアントは現在、ユーザーのブラウザーから認可レスポンスを受信するのを待っている。¶
code_challenge=hash(xyz)を認可
リクエストで使用する。攻撃者はそのリクエストを傍受し、
code_challengeパラメーター全体をリクエストから削除する。
このステップは攻撃者のデバイス上で実行されるため、攻撃者は
たとえばブラウザーデバッグツールを使用して、リクエスト内容へ完全にアクセスできる。¶
code_verifier=abcを送信する。¶
code_verifierパラメーターの存在または内容を検査しない。
認可サーバーは、攻撃者のリソースに属するアクセストークンを、ユーザーの制御下にある
クライアントへ発行する。¶
stateを適切に使用すれば、この攻撃を防止できる。
しかし、実務上、多くのOAuthクライアントがstateを使用していない、
または適切に検査していないことが示されている。¶
したがって、認可サーバーはこの攻撃を緩和 MUSTしなければならない。¶
認可サーバーの観点からは、上記の攻撃では、
その認可コードが発行されたOAuthフローの認可リクエストに
code_challengeパラメーターが存在しなかったにもかかわらず、
トークンエンドポイントでcode_verifierパラメーターが受信される点に注意すること。¶
この事実は、この攻撃を緩和するために使用できる。 [RFC7636]はすでに次を義務付けている。¶
code_challengeが存在した場合、
トークンリクエストには有効なcode_verifierが存在しなければならない。¶
これに加えて、PKCEダウングレード攻撃を防止するため、
認可サーバーは、認可リクエストにcode_challengeが存在しなかった場合、
code_verifierを含むトークンエンドポイントへのリクエストが拒否されることを保証
MUSTしなければならない。¶
PKCEの使用を(一般に、または特定のクライアントについて) 義務付ける認可サーバーは、このセキュリティ対策を暗黙的に実装している。¶
アクセストークンは、特定の状況下でリソースサーバーから漏えいする可能性がある。¶
攻撃者は自身のリソースサーバーを設定し、 他のリソースサーバーに対して有効なアクセストークンをそこへ送信するよう クライアントをだます可能性がある (Section 3の攻撃者 (A1)および (A5)を参照)。 クライアントが有効なアクセストークンをこの偽造リソースサーバーへ送信した場合、 攻撃者はそのトークンを使用して、リソース所有者に代わって他のサービスへアクセスできる。¶
この攻撃は、クライアントが開発時に1つの特定のリソースサーバー (およびそのURL)に結び付けられておらず、クライアントインスタンスに実行時に リソースサーバーURLが提供されることを仮定している。 この種の遅延バインディングは、クライアントが標準化されたAPI (たとえばメール、カレンダー、eHealth、またはオープンバンキング向け)を実装するサービスを 使用し、クライアントがユーザーまたは管理者によって設定される状況で典型的である。¶
攻撃者は、特定のデプロイメントのリソースへアクセスするために リソースサーバーを侵害する可能性がある。このような侵害は、たとえばログファイルへの 部分的なアクセスから、当該サーバーの完全な制御まで幅があり、その場合、すべての制御を 回避し、すべてのリソースへアクセスできる。 攻撃者はまた、侵害されたシステム上に保持され、他のリソースサーバーへの アクセスに有効である可能性のある他のアクセストークンも取得できる。¶
サーバーシステムの堅牢化と監視によってサーバー侵害を防止することは、 標準的な運用手順と見なされるため、本文書の範囲外である。 Section 4.9は、 OAuth関連の侵害の影響と、捕捉されたアクセストークンのリプレイに焦点を当てる。¶
悪意ある行為者によるアクセストークンリプレイに対処するため、 実装者は次の対策を考慮すべきである。¶
第一および第二の推奨事項は、アクセストークンが漏えいする他の シナリオにも適用される(Section 3の 攻撃者(A5)を参照)。¶
アクセストークンは、たとえばSections 4.1、 4.2、4.3、4.4、および 4.9で説明される攻撃を通じて、 さまざまな方法で攻撃者に盗まれる可能性がある。これらの攻撃の一部は、それぞれのセクションで 説明される特定のセキュリティ対策によって緩和できる。しかし、場合によっては、 これらの対策が十分でない、または正しく実装されていないことがある。 したがって、認可サーバーは、以下で説明するようにアクセストークンが送信者制約付きであり、 オーディエンス制限付きであることを保証 SHOULDする。アーキテクチャ上および性能上の理由により、 一部のデプロイメントではこれらの対策の使用が妨げられる可能性がある。¶
名前が示すように、送信者制約付きアクセストークンは、 アクセストークンの適用範囲を特定の送信者に限定する。 この送信者は、リソースサーバーでそのトークンが受け入れられる前提条件として、 特定の秘密を知っていることを示す義務を負う。¶
典型的なフローは次のようになる。¶
所有証明を使用する送信者制約付きアクセストークンの方法として、 OAuthワーキンググループによって定義され、実際に使用されているものが2つある。¶
攻撃者がトークンと鍵素材の両方にアクセスできるようになると、 送信者制約付きトークンのセキュリティは損なわれる点に注意すること。 これは特に、破損したクライアントソフトウェアや(クライアントがブラウザー内で実行されている場合の) クロスサイトスクリプティング攻撃に該当する。鍵素材がハードウェアまたはソフトウェアの セキュリティモジュール内で保護されている、または(TLSスタックのように)間接的にしか アクセスできない場合、送信者制約付きトークンは少なくとも、クライアントがオフラインのとき、 すなわちセキュリティモジュールまたはインターフェイスが攻撃者に利用できないときに、 トークンの使用から保護する。これはアクセストークンだけでなくリフレッシュトークンにも適用される (Section 4.14を参照)。¶
オーディエンス制限は、本質的にアクセストークンを 特定のリソースサーバーに制限する。認可サーバーはアクセストークンを 特定のリソースサーバーに関連付け、リソースサーバーは意図されたオーディエンスを 検証することになっている。アクセストークンが意図されたオーディエンスの検証に失敗した場合、 リソースサーバーは対応するリクエストの処理を拒否する。¶
一般に、オーディエンス制限はトークン漏えいの影響を制限する。 偽造リソースサーバーの場合には、以下で説明するように、フィッシングされたアクセストークンが 正当なリソースサーバーで悪用されることも防止できる可能性がある。¶
オーディエンスは、論理名または物理アドレス (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]を使用すると、クライアントは複数の リソースサーバーでアクセストークンを使用できる。¶
オーディエンス制限、または一般的に言えば、 クライアントがアクセストークンをどこで使用したいかを認可サーバーに示すことは、 トークン漏えい防止の範囲を超える追加の利点を持つ点に注意すべきである。 それらにより、認可サーバーは、当該サーバー向けに特化して作成された形式および内容を持つ 異なるアクセストークンを作成できる。これは、構造化アクセストークンを使用する デプロイメントにおいて、大きな機能上およびプライバシー上の利点を持つ。¶
認可サーバーは、アクセストークンを安全に使用できる場所について 追加情報をクライアントへ提供できる。このアプローチと、それが推奨されない理由を 以下で論じる。¶
最も単純な形では、認可サーバーが既知のリソースサーバーのリストを
公開する必要がある。次の例は、非標準のAuthorization Server Metadataパラメーター
resource_serversを使用して示している。¶
認可サーバーは、アクセストークンが有効なURLを
トークンレスポンスで返すこともできる。次の例は、非標準の戻りパラメーター
access_token_resource_serverを使用して示している。¶
この緩和戦略は、クライアントがセキュリティポリシーを強制し、
正当な宛先にのみアクセストークンを送信することに依存する。
OAuth関連のセキュリティ研究の結果(たとえば
[research.ubc]および
[research.cmu]を参照)は、
クライアント実装の大部分が、state検査のようなセキュリティ制御を
実装していない、または適切に実装できていないことを示している。
したがって、アクセストークンフィッシングの防止をクライアントに依存することも
失敗する可能性が高い。さらに、クライアントと認可サーバーおよびリソースサーバーの
比率を考えると、セキュリティ関連ロジックを可能な限りこれらのサーバーへ移すことが
より実現可能なアプローチと見なされる。
明らかに、クライアントは全体的なセキュリティに貢献しなければならない。
しかし、4.10.1および4.10.2で説明されるような、関係当事者間の
より良いバランスを提供する代替対策がある。¶
認可サーバーまたはクライアントにオープンリダイレクターがある場合、 次の攻撃が発生し得る。そのようなエンドポイントは、たとえばユーザーが外部Webサイトへ リダイレクトされる前にメッセージを表示するため、またはログインプロンプトなどで中断される前に 訪問しようとしていたURLへユーザーを戻すために実装されることがある。¶
クライアントはオープンリダイレクターを公開しては MUST NOTならない。攻撃者はオープンリダイレクターを使用して、 クライアントを指すURLを生成し、それを利用して Section 4.1.2で説明されるように 認可コードおよびアクセストークンを流出させる可能性がある。 別の悪用ケースは、クライアントを指しているように見えるURLを生成することである。 これにより、ユーザーはそのURLを信頼してブラウザーで開くようだまされる可能性がある。 これはフィッシングに悪用できる。¶
オープンリダイレクションを防止するため、クライアントは、 ターゲットURLが許可されている場合、またはリクエストの起源および完全性を認証できる場合に のみリダイレクトすべきである。オープンリダイレクションに対する対策は OWASP [owasp.redir]で説明されている。¶
認可エンドポイントでは、典型的なプロトコルフローとして、 認可サーバーがユーザーにフォームでクレデンシャルの入力を促し、そのフォームが (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する。¶
HTTPアプリケーションの一般的なデプロイメントアーキテクチャは、 TLS接続を終端し、受信リクエストを対応するアプリケーションサーバーノードへ ディスパッチするリバースプロキシの背後にアプリケーションサーバーを隠すことである。¶
本セクションでは、OAuthに関連するこのデプロイメントアーキテクチャの 攻撃角度をいくつか取り上げ、セキュリティ制御に関する推奨事項を示す。¶
状況によっては、リバースプロキシはさらなる処理のために セキュリティ関連データを上流のアプリケーションサーバーへ渡す必要がある。 例には、リクエスト送信元のIPアドレス、token-binding ID、認証されたTLSクライアント証明書が含まれる。 このデータは通常、上流リクエストに追加されたHTTPヘッダーで渡される。 ヘッダーは多くの場合カスタムのアプリケーション固有ヘッダーであるが、 クライアント証明書およびクライアント証明書チェーンの標準化されたヘッダーフィールドは [RFC9440]で定義されている。¶
リバースプロキシが外部から送信された任意のヘッダーを通過させる場合、
攻撃者は、その方法でセキュリティ制御を回避するために、偽のヘッダー値を
プロキシ経由でアプリケーションサーバーへ直接送信しようとする可能性がある。
たとえば、リバースプロキシがX-Forwarded-Forヘッダーを受け入れ、
受信リクエストの送信元を単に追加する(リストにする)ことは標準的な慣行である。
アプリケーションサーバーで実行されるロジックによっては、攻撃者は単に許可されたIPアドレスを
ヘッダーに追加し、保護を無意味にできる可能性がある。¶
したがって、リバースプロキシは、アプリケーションサーバーの セキュリティに関連するすべてのヘッダー値の真正性および完全性を保証するために、 受信リクエストをサニタイズ MUSTしなければならない。¶
攻撃者がプロキシとアプリケーションサーバーの間の内部ネットワークへ アクセスできる場合、設置されているセキュリティ制御を回避しようとする可能性もある。 したがって、通信エンティティの真正性を保証することが不可欠である。 さらに、リバースプロキシとアプリケーションサーバーの間の通信リンクは、 メッセージの盗聴、注入、およびリプレイから保護され MUSTなければならない。¶
リフレッシュトークンは、新しいアクセストークンを取得するための 便利でユーザーフレンドリーな方法である。また、認可サーバーが短い有効期間かつ 縮小されたスコープのアクセストークンを発行できるようにし、アクセストークン漏えいの 潜在的影響を低減するため、OAuthのセキュリティにも寄与する。¶
リフレッシュトークンは攻撃者にとって魅力的な標的である。 なぜなら、特定のクライアントに付与されたアクセスの全範囲を表し、 特定のリソースにさらに制約されていないためである。 攻撃者がリフレッシュトークンを流出させ、それを正常にリプレイできる場合、 攻撃者はアクセストークンを発行し、リソース所有者に代わってそれらを使用して リソースサーバーへアクセスできる。¶
[RFC6749]は、 次を要求することで、すでに堅牢なベースライン保護を提供している。¶
[RFC6749]は、 それぞれのエラーコードおよびレスポンス挙動を定義することで、 リフレッシュトークンの有効期限および失効、ならびにリフレッシュトークンローテーションのような さらなる(実装固有の)セキュリティ対策の基盤も築いている。¶
認可サーバーは、リスク評価に基づき、特定のクライアントへ リフレッシュトークンを発行するかどうかを判断 MUSTしなければならない。認可サーバーが リフレッシュトークンを発行しないと決定した場合、クライアントは認可コードグラントタイプのような 他のグラントタイプを利用することで新しいアクセストークンを取得 MAYできる。そのような場合、認可サーバーはユーザー体験を最適化するために、 Cookieおよび永続的グラントを利用できる。¶
リフレッシュトークンが発行される場合、それらのリフレッシュトークンは、 リソース所有者が同意したスコープおよびリソースサーバーに結び付けられ MUSTなければならない。これは、正当なクライアントによる権限昇格を防止し、 リフレッシュトークン漏えいの影響を低減するためである。¶
コンフィデンシャルクライアントについては、[RFC6749]がすでに、 リフレッシュトークンは発行先のクライアントによってのみ使用できることを要求している。¶
認可サーバーは、パブリッククライアントについて、 悪意ある行為者によるリフレッシュトークンリプレイを検出するために、次の方法のいずれかを利用 MUSTしなければならない。¶
リフレッシュトークンローテーション: 認可サーバーは、アクセストークン更新レスポンスごとに新しいリフレッシュトークンを発行する。 以前のリフレッシュトークンは無効化されるが、関係に関する情報は 認可サーバーに保持される。リフレッシュトークンが侵害され、その後攻撃者と 正当なクライアントの両方によって使用された場合、その一方が無効化された リフレッシュトークンを提示し、それによって認可サーバーに侵害を知らせる。 認可サーバーは、どちらの当事者が無効なリフレッシュトークンを提出したかを 判断できないが、アクティブなリフレッシュトークンを失効させる。 これにより、正当なクライアントに新しい認可グラントを取得させる代償を伴って、 攻撃を停止する。¶
実装上の注意: リフレッシュトークンが属するグラントは、 リフレッシュトークン自体にエンコードされてもよい。これにより、認可サーバーは リフレッシュトークンが属するグラント、および拡張して失効させる必要があるすべての リフレッシュトークンを効率的に判断できる。認可サーバーは、この場合、たとえば 署名を使用して、リフレッシュトークン値の完全性を保証 MUSTしなければならない。¶
認可サーバーは、次のようなセキュリティイベントが発生した場合に、 リフレッシュトークンを自動的に失効 MAYさせることができる。¶
クライアントが一定期間非アクティブであった場合、 すなわち、リフレッシュトークンが一定期間新しいアクセストークンの取得に使用されていない場合、 リフレッシュトークンは期限切れになる SHOULDである。有効期限は認可サーバーの裁量に委ねられる。 これはグローバルな値であっても、クライアントポリシーまたはリフレッシュトークンに関連付けられた グラント(およびその機微性)に基づいて決定されてもよい。¶
リソースサーバーは、アクセストークンが発行されたリソース所有者の
アイデンティティ、またはクライアントクレデンシャルグラントにおけるクライアントの
アイデンティティに基づいてアクセス制御判断を行う場合がある。たとえば、
[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]を使用する実装だけでなく、 類似した独自ソリューションにも影響する可能性がある。¶
認可サーバーは、クライアントIDとユーザー識別子のための
共通名前空間が存在する場合、たとえば上記Section
4.15で示した
[RFC9068]のsubクレーム例のような場合、
クライアントが自身のclient_idまたは本物のリソース所有者との混同を
引き起こし得るその他のクレームに影響を与えることを許可すべきでは
SHOULD NOTない。これを回避できない場合、
認可サーバーは、リソースサーバーが2種類のアクセストークンを区別するための
他の手段を提供
MUSTしなければならない。¶
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ページ上で実行が許可されるスクリプトの
ソースを制限するポリシーを組み合わせることにより、クリックジャッキングに対する
堅牢な保護機構を提供する。このようなポリシーの非規範的な例を次のリストに示す。¶
一部のユーザーエージェントは[W3C.CSP-2]をサポートしないため、 そのようなレガシーユーザーエージェントが認可サーバーによって明示的にサポート外とされていない限り、 この技術は[RFC6819]で説明されるものを含む 他の技術と組み合わせる SHOULDである。そのような場合でも、追加の対策はなお採用される SHOULDである。¶
認可レスポンスがHTTPリダイレクトの代わりに postMessage [WHATWG.postmessage_api]のようなブラウザー内通信技術で 送信される場合、メッセージが意図せず悪意あるオリジンへ送信される、または 悪意あるオリジンから注入される可能性がある。¶
ブラウザー内通信を使用する攻撃の次の非規範的な擬似コード例は、 [research.rub]で説明されている。¶
postMessageを介して認可レスポンスまたはトークンレスポンスを 送信する場合、認可サーバーはクライアントのオリジンではなくワイルドカードオリジン "*"へレスポンスを送信する。レスポンスが送信されるウィンドウが攻撃者に制御されている場合、 攻撃者はレスポンスを読み取ることができる。¶
window.opener.postMessage(
{
code: "ABC",
state: "123"
},
"*" // any website in the opener window can receive the message
)
¶
postMessageを介して認可レスポンスまたはトークンレスポンスを 送信する場合、認可サーバーは受信者オリジンをリダイレクトURIと照合しない可能性があり、 代わりに、たとえば攻撃者が提供したオリジンへレスポンスを送信する可能性がある。 これはSection 4.1で説明された攻撃に類似している。¶
window.opener.postMessage(
{
code: "ABC",
state: "123"
},
"https://attacker.example" // attacker-provided value
)
¶
postMessageを介して認可レスポンスまたはトークンレスポンスを 期待するクライアントは、メッセージの送信者オリジンを検証しない可能性がある。 これにより、攻撃者が認可レスポンスまたはトークンレスポンスをクライアントへ 注入できる可能性がある。¶
悪意を持って注入された認可レスポンスの場合、 この攻撃はSection 4.7で説明されるCSRF攻撃の変種である。 Section 4.7で説明される対策は、この攻撃にも適用される。¶
悪意を持って注入されたトークンレスポンスの場合、 Section 4.10.1で説明される 送信者制約付きアクセストークンは、状況によっては攻撃を防止する可能性があるが、 一般にはSection 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なければならない。¶
本文書にはIANAによる処置はない。¶
貴重なフィードバックを寄せてくださった 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 に感謝する。¶