Internet Engineering Task Force (IETF) A. Parecki
Request for Comments: 10017 Okta
BCP: 212 P. De Ryck
Category: Best Current Practice Pragmatic Web Security
ISSN: 2070-1721 D. Waite
Ping Identity
August 2026
This specification details the threats, attack consequences, security considerations, and best practices that must be taken into account when developing browser-based applications that use OAuth 2.0.
この仕様では、OAuth 2.0 を使用するブラウザベースのアプリケーションを開発する際に考慮する必要がある脅威、攻撃の影響、セキュリティに関する考慮事項、ベスト プラクティスについて詳しく説明します。
This memo documents an Internet Best Current Practice.
このメモは、インターネットの現在のベスト プラクティスを文書化したものです。
This document is a product of the Internet Engineering Task Force (IETF). It represents the consensus of the IETF community. It has received public review and has been approved for publication by the Internet Engineering Steering Group (IESG). Further information on BCPs is available in Section 2 of RFC 7841.
このドキュメントは Internet Engineering Task Force (IETF) の成果物です。これは IETF コミュニティのコンセンサスを表しています。この文書は公開レビューを受け、Internet Engineering Steering Group (IESG) によって公開が承認されています。BCP の詳細については、RFC 7841 のセクション 2 を参照してください。
Information about the current status of this document, any errata, and how to provide feedback on it may be obtained at https://www.rfc-editor.org/info/rfc10017.
この文書の現在のステータス、正誤表、およびそれに対するフィードバックの提供方法に関する情報は、https://www.rfc-editor.org/info/rfc10017 で入手できます。
Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved.
Copyright (c) 2026 IETF Trust および文書の著者として特定された人物。無断転載を禁じます。
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.
この文書は、BCP 78 およびこの文書の発行日に有効な IETF 文書に関する IETF トラストの法的規定 (https://trustee.ietf.org/license-info) の対象となります。これらの文書には、この文書に関するお客様の権利と制限が記載されているため、注意深くお読みください。この文書から抽出されたコード コンポーネントには、トラスト法的規定のセクション 4.e に記載されている改訂 BSD ライセンス テキストが含まれている必要があり、改訂 BSD ライセンスに記載されているように保証なしで提供されます。
1. Introduction
2. Notational Conventions
3. Terminology
4. History of OAuth 2.0 in Browser-Based Applications
5. The Threat of Malicious JavaScript
5.1. Attack Scenarios
5.1.1. Single-Execution Token Theft
5.1.2. Persistent Token Theft
5.1.3. Acquisition and Extraction of New Tokens
5.1.4. Proxying Requests via the User's Browser
5.2. Attack Consequences
5.2.1. Exploiting Stolen Refresh Tokens
5.2.2. Exploiting Stolen Access Tokens
5.2.3. Client Hijacking
6. Application Architecture Patterns
6.1. Backend for Frontend (BFF)
6.1.1. Application Architecture
6.1.2. Implementation Details
6.1.3. Security Considerations
6.1.4. Threat Analysis
6.2. Token-Mediating Backend
6.2.1. Application Architecture
6.2.2. Implementation Details
6.2.3. Security Considerations
6.2.4. Threat Analysis
6.3. Browser-Based OAuth 2.0 Client
6.3.1. Application Architecture
6.3.2. Implementation Details
6.3.3. Security Considerations
6.3.4. Threat Analysis
7. Discouraged and Deprecated Architecture Patterns
7.1. Single-Domain Browser-Based Applications (Not Using OAuth)
7.1.1. Threat Analysis
7.2. OAuth Implicit Grant
7.2.1. Historic Note
7.2.2. Threat Analysis
7.2.3. Further Attacks on the Implicit Grant
7.2.4. Disadvantages of the Implicit Grant
7.3. Resource Owner Password Credentials Grant
7.4. Handling the OAuth Flow in a Service Worker
7.4.1. Threat Analysis
8. Token Storage in the Browser
8.1. Cookies
8.2. Token Storage in a Service Worker
8.3. Token Storage in a Web Worker
8.4. In-Memory Token Storage
8.5. Persistent Token Storage
8.6. Filesystem Considerations for Browser Storage APIs
9. Security Considerations
9.1. Reducing the Authority of Tokens
9.2. Sender-Constrained Tokens
9.3. Authorization Server Mix-Up Mitigation
9.4. Isolating Applications Using Origins
10. IANA Considerations
11. References
11.1. Normative References
11.2. Informative References
Acknowledgements
Authors' Addresses
This specification describes different architectural patterns for implementing OAuth 2.0 clients in applications executing in a browser. It also outlines the security challenges for browser-based applications and analyzes how different patterns can help address some of these challenges.
この仕様では、ブラウザで実行されるアプリケーションに OAuth 2.0 クライアントを実装するためのさまざまなアーキテクチャ パターンについて説明します。また、ブラウザベースのアプリケーションのセキュリティ課題についても概説し、さまざまなパターンがこれらの課題のいくつかに対処するのにどのように役立つかを分析します。
This document focuses on JavaScript frontend applications acting as the OAuth client (defined in Section 1.1 of [RFC6749]), interacting with the authorization server (Section 1.1 of [RFC6749]) to obtain access tokens and optionally refresh tokens. The client uses the access token to access protected resources on resource servers (Section 1.1 of [RFC6749]). When using OAuth, the client, authorization server, and resource servers are all considered independent parties, regardless of whether each is owned or operated by the same entity.
この文書は、OAuth クライアント ([RFC6749] のセクション 1.1 で定義) として機能し、認可サーバー ([RFC6749] のセクション 1.1) と対話してアクセス トークンを取得し、必要に応じてリフレッシュ トークンを取得する JavaScript フロントエンド アプリケーションに焦点を当てます。クライアントはアクセス トークンを使用して、リソース サーバー上の保護されたリソースにアクセスします ([RFC6749] のセクション 1.1)。OAuth を使用する場合、クライアント、認可サーバー、およびリソース サーバーは、それぞれが同じエンティティによって所有または運営されているかどうかに関係なく、すべて独立した当事者とみなされます。
Note that many web applications consist of a frontend and API running on a common domain, allowing for an architecture that does not rely on OAuth 2.0. This is described in more detail in Section 7.1. Such scenarios can rely on OpenID Connect [OpenID] for federated user authentication, after which the application maintains the user's authentication state. Such a scenario (which only uses OAuth 2.0 as the underlying specification of OpenID Connect) is not within scope of this specification.
多くの Web アプリケーションは、共通ドメインで実行されるフロントエンドと API で構成されており、OAuth 2.0 に依存しないアーキテクチャが可能であることに注意してください。これについてはセクション 7.1 で詳しく説明します。このようなシナリオでは、フェデレーション ユーザー認証に OpenID Connect [OpenID] を利用することができ、その後、アプリケーションはユーザーの認証状態を維持します。このようなシナリオ (OpenID Connect の基礎となる仕様として OAuth 2.0 のみを使用する) は、この仕様の範囲内ではありません。
For native application developers using OAuth 2.0 and OpenID Connect, an IETF BCP (Best Current Practice) was published that guides integration of these technologies. That document is formally known as [RFC8252] or BCP 212 but is often referred to as "AppAuth" after the OpenID Foundation-sponsored set of libraries that assist developers in adopting these practices. [RFC8252] makes specific recommendations for how to securely implement OAuth clients in native applications, including incorporating additional OAuth extensions where needed.
OAuth 2.0 と OpenID Connect を使用するネイティブ アプリケーション開発者向けに、これらのテクノロジーの統合をガイドする IETF BCP (Best Current Practice) が公開されました。この文書は正式には [RFC8252] または BCP 212 として知られていますが、開発者がこれらのプラクティスを採用するのを支援する OpenID Foundation が後援する一連のライブラリにちなんで「AppAuth」と呼ばれることもよくあります。[RFC8252] では、必要に応じて追加の OAuth 拡張機能を組み込むなど、ネイティブ アプリケーションで OAuth クライアントを安全に実装する方法について具体的な推奨事項を示しています。
This specification, "OAuth 2.0 for Browser-Based Applications", highlights how the security properties of browser-based applications are vastly different than those of native applications, and it addresses the similarities between implementing OAuth clients as native applications and browser-based applications. This document is primarily focused on OAuth, except where OpenID Connect provides additional considerations.
この仕様「OAuth 2.0 for Browser-Based Applications」では、ブラウザベースのアプリケーションのセキュリティ特性がネイティブ アプリケーションのセキュリティ特性と大きく異なることを強調し、OAuth クライアントをネイティブ アプリケーションとして実装する場合とブラウザベースのアプリケーションとして実装する場合の類似点についても取り上げています。このドキュメントは、OpenID Connect が追加の考慮事項を提供する場合を除き、主に OAuth に焦点を当てています。
Many of these recommendations are derived from the Best Current Practice for OAuth 2.0 Security [RFC9700], as browser-based applications are expected to follow those recommendations as well. This document expands on and further restricts various recommendations given in [RFC9700].
これらの推奨事項の多くは、OAuth 2.0 セキュリティの現在のベスト プラクティス [RFC9700] に基づいており、ブラウザベースのアプリケーションもこれらの推奨事項に従うことが期待されています。この文書は、[RFC9700] で与えられたさまざまな推奨事項を拡張し、さらに制限します。
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.
このドキュメント内のキーワード「MUST」、「MUST NOT」、「REQUIRED」、「SHALL」、「SHALL NOT」、「SHOULD」、「SHOULD NOT」、「RECOMMENDED」、「NOT RECOMMENDED」、「MAY」、および「OPTIONAL」は、ここに示すようにすべて大文字で表示されている場合にのみ、BCP 14 [RFC2119] [RFC8174] で説明されているように解釈されます。
This specification uses the terms "access token", "authorization endpoint", "authorization grant", "authorization server", "client", "client identifier" (client ID), "protected resource", "refresh token", "resource server", and "token endpoint" as defined by OAuth 2.0 [RFC6749]. It uses "bearer token" as defined by [RFC6750].
この仕様では、OAuth 2.0 [RFC6749] で定義されている「アクセス トークン」、「認可エンドポイント」、「認可付与」、「認可サーバー」、「クライアント」、「クライアント識別子」(クライアント ID)、「保護されたリソース」、「リフレッシュ トークン」、「リソース サーバー」、および「トークン エンドポイント」という用語が使用されます。[RFC6750] で定義されている「ベアラー トークン」を使用します。
In addition to the terms defined in referenced specifications, this document uses the following terms:
参照仕様で定義されている用語に加えて、このドキュメントでは次の用語が使用されます。
OAuth:
OAuth:
In this document, "OAuth" refers to "OAuth 2.0" [RFC6749] [RFC6750].
この文書では、「OAuth」は「OAuth 2.0」[RFC6749] [RFC6750]を指します。
Browser-based application:
ブラウザベースのアプリケーション:
An application that is dynamically downloaded and executed in a web browser, usually written in JavaScript. Also sometimes referred to as a "single-page application" or "SPA".
動的にダウンロードされて Web ブラウザーで実行されるアプリケーション。通常は JavaScript で記述されます。「シングルページ アプリケーション」または「SPA」と呼ばれることもあります。
This document discusses the security of browser-based applications, which are executed by the browser in a runtime environment. In most scenarios, these applications are JavaScript applications running in a JavaScript execution environment. Given the popularity of this scenario, this document uses the term "JavaScript" to refer to all mechanisms that allow code to execute in the application's runtime in the browser. The recommendations and considerations in this document are not exclusively linked to the JavaScript language or its runtime but also apply to other languages and runtime environments in the browser, such as WebAssembly (WASM) [W3C.wasm-core-2].
この文書では、ランタイム環境でブラウザによって実行されるブラウザベースのアプリケーションのセキュリティについて説明します。ほとんどのシナリオでは、これらのアプリケーションは、JavaScript 実行環境で実行される JavaScript アプリケーションです。このシナリオの人気を考慮して、このドキュメントでは、ブラウザーのアプリケーションのランタイムでコードを実行できるようにするすべてのメカニズムを指すために「JavaScript」という用語を使用します。この文書の推奨事項と考慮事項は、JavaScript 言語またはそのランタイムに限定されるものではなく、WebAssembly (WASM) [W3C.wasm-core-2] などのブラウザーの他の言語やランタイム環境にも当てはまります。
PKCE:
PKCE:
Proof Key for Code Exchange [RFC7636]. A mechanism that prevents various attacks on OAuth authorization codes.
コード交換用の証明キー [RFC7636]。OAuth認可コードに対するさまざまな攻撃を防ぐ仕組み。
DPoP:
DEPoP:
Demonstrating Proof of Possession [RFC9449]. An OAuth 2.0 mechanism that restricts access tokens for use only by the client they were issued to.
所有証明の実証[RFC9449]。アクセス トークンの使用を、発行先のクライアントのみに制限する OAuth 2.0 メカニズム。
CORS:
コルス:
Cross-Origin Resource Sharing [Fetch]. A mechanism that enables exceptions to the browser's same-origin policy.
クロスオリジンリソース共有 [フェッチ]。ブラウザーの同一生成元ポリシーの例外を有効にするメカニズム。
CSP:
CSP:
Content Security Policy [W3C.CSP3]. A mechanism that restricts which resources a particular web page can fetch or execute.
コンテンツ セキュリティ ポリシー [W3C.CSP3]。特定の Web ページが取得または実行できるリソースを制限するメカニズム。
At the time that OAuth 2.0 was initially specified in [RFC6749] and [RFC6750], browser-based JavaScript applications needed a solution that strictly complied with the same-origin policy. Common deployments of OAuth 2.0 involved an application running on a different domain than the authorization server, so it was historically not possible to use the Authorization Code grant type (Section 4.1 of [RFC6749]), which would require a cross-origin POST request. This limitation was one of the motivations for the definition of the Implicit grant (Section 4.2 of [RFC6749]), which returns the access token in the front channel via the fragment part of the URL, bypassing the need for a cross-origin POST request.
OAuth 2.0 が最初に [RFC6749] および [RFC6750] で規定された時点では、ブラウザベースの JavaScript アプリケーションには同一生成元ポリシーに厳密に準拠するソリューションが必要でした。OAuth 2.0 の一般的なデプロイメントには、認可サーバーとは異なるドメインで実行されるアプリケーションが含まれていたため、クロスオリジン POST リクエストが必要となる認可コード付与タイプ ([RFC6749] のセクション 4.1) を使用することは歴史的に不可能でした。この制限は、Implicit Grant ([RFC6749] のセクション 4.2) の定義の動機の 1 つであり、URL のフラグメント部分を介してフロント チャネルでアクセス トークンを返し、クロスオリジン POST リクエストの必要性を回避します。
However, there are several drawbacks to the Implicit grant, generally involving vulnerabilities associated with the exposure of the access token in the URL. See Section 7.2 for an analysis of these attacks and the drawbacks of using the Implicit grant in browsers. Additional attacks and security considerations can be found in [RFC9700].
ただし、Implicit Grant にはいくつかの欠点があり、一般に URL 内のアクセス トークンの露出に関連する脆弱性が関係します。これらの攻撃の分析と、ブラウザで暗黙的許可を使用する場合の欠点については、セクション 7.2 を参照してください。追加の攻撃とセキュリティに関する考慮事項は、[RFC9700] に記載されています。
In modern web development, widespread adoption of Cross-Origin Resource Sharing (CORS) [Fetch] (which enables exceptions to the same-origin policy) allows browser-based applications to use the OAuth 2.0 Authorization Code flow and make a POST request to exchange the authorization code for an access token at the token endpoint. Since the Authorization Code grant type enables the use of refresh tokens, this behavior has been adopted for browser-based clients as well, even though these clients are still public clients (defined in Section 2.1 of [RFC6749]) with limited to no access to secure storage. Furthermore, adding Proof Key for Code Exchange (PKCE) [RFC7636] to the flow prevents authorization code injection as well as ensures that even if an authorization code is intercepted, it is unusable by an attacker.
最新の Web 開発では、Cross-Origin Resource Sharing (CORS) [Fetch] (同一オリジン ポリシーの例外を有効にする) が広く採用されているため、ブラウザベースのアプリケーションで OAuth 2.0 認証コード フローを使用し、トークン エンドポイントでアクセス トークンの認証コードを交換する POST リクエストを行うことができます。認可コード付与タイプではリフレッシュ トークンの使用が有効になっているため、ブラウザ ベースのクライアントが依然としてパブリック クライアント ([RFC6749] のセクション 2.1 で定義) であり、安全なストレージへのアクセスが制限されているにもかかわらず、この動作がブラウザ ベースのクライアントにも採用されています。さらに、Proof Key for Code Exchange (PKCE) [RFC7636] をフローに追加すると、認可コードのインジェクションが防止され、たとえ認可コードが傍受された場合でも攻撃者がそのコードを使用できなくなります。
For this reason, and from other lessons learned, the current best practice for browser-based applications is to use the OAuth 2.0 Authorization Code grant type with PKCE. There are various architectural patterns for deploying browser-based applications, both with and without a corresponding server-side component. Each of these architectures has specific trade-offs and considerations that are discussed further in this document. Additional considerations apply for first-party common-domain applications.
この理由と、他の教訓から、ブラウザベースのアプリケーションの現在のベスト プラクティスは、PKCE で OAuth 2.0 認証コード付与タイプを使用することです。ブラウザベースのアプリケーションを展開するには、対応するサーバー側コンポーネントの有無にかかわらず、さまざまなアーキテクチャ パターンがあります。これらの各アーキテクチャには、このドキュメントでさらに詳しく説明する特定のトレードオフと考慮事項があります。ファーストパーティの共通ドメイン アプリケーションには追加の考慮事項が適用されます。
Malicious JavaScript poses a significant risk to browser-based applications. Attack vectors, such as cross-site scripting (XSS) or the compromise of remote code files, give an attacker the capability to run arbitrary code in the application's execution context. This malicious code is not isolated from the main application's code in any way. Consequently, the malicious code can not only take control of the running execution context but also perform actions within the application's origin. Concretely, this means that the malicious code can steal data from the current page, interact with other same-origin browsing contexts, send requests to a backend from within the application's origin, steal data from origin-based storage mechanisms (e.g., localStorage, IndexedDB), etc.
悪意のある JavaScript は、ブラウザベースのアプリケーションに重大なリスクをもたらします。クロスサイト スクリプティング (XSS) やリモート コード ファイルの侵害などの攻撃ベクトルにより、攻撃者はアプリケーションの実行コンテキストで任意のコードを実行できるようになります。この悪意のあるコードは、メイン アプリケーションのコードから決して分離されていません。その結果、悪意のあるコードは、実行中の実行コンテキストを制御するだけでなく、アプリケーションのオリジン内でアクションを実行することもできます。具体的には、悪意のあるコードが現在のページからデータを盗み、他の同じオリジンの閲覧コンテキストと対話し、アプリケーションのオリジン内からバックエンドにリクエストを送信し、オリジンベースのストレージ メカニズム (localStorage、IndexedDB など) からデータを盗むことができることを意味します。
First and foremost, it is crucial to take proactive measures to avoid the attacker from gaining a foothold in the first place. Doing so involves, but is not limited to, the following:
何よりもまず、攻撃者が足がかりを作らないように事前の対策を講じることが重要です。これには次のことが含まれますが、これらに限定されません。
* Strictly applying context-sensitive output encoding and sanitization when handling untrusted data
* 信頼できないデータを処理する場合は、コンテキスト依存の出力エンコードとサニタイズを厳密に適用する
* Limiting or avoiding the loading of unchecked third-party resources
* 未チェックのサードパーティリソースの読み込みを制限または回避する
* Using Subresource Integrity [W3C.SRI] to restrict valid scripts that can be loaded
* サブリソース整合性 [W3C.SRI] を使用してロードできる有効なスクリプトを制限する
* Using a nonce-based or hash-based Content Security Policy (CSP) [W3C.CSP3] to prevent the execution of unauthorized script code
* ノンスベースまたはハッシュベースのコンテンツ セキュリティ ポリシー (CSP) [W3C.CSP3] を使用して、不正なスクリプト コードの実行を防止する
* Using origin isolation and HTML5 sandboxing to create boundaries between different parts of the application
* オリジン分離と HTML5 サンドボックスを使用して、アプリケーションの異なる部分間に境界を作成する
Further recommendations can be found in the Open Worldwide Application Security Project (OWASP) Cheat Sheet series [OWASPCheatSheet].
さらに詳しい推奨事項は、Open Worldwide Application Security Project (OWASP) Cheat Sheet シリーズ [OWASPCheatSheet] に記載されています。
Unfortunately, history shows that even when applying these security guidelines, there is a risk that the attacker might find a way to trigger the execution of malicious JavaScript. When analyzing the security of browser-based applications in light of the presence of malicious JavaScript, it is crucial to realize that the *malicious JavaScript code has the same privileges as the legitimate application code*. All JavaScript applications are exposed to this risk in some degree.
残念なことに、歴史によれば、これらのセキュリティ ガイドラインを適用した場合でも、攻撃者が悪意のある JavaScript の実行をトリガーする方法を見つけてしまう危険性があります。悪意のある JavaScript の存在を考慮してブラウザベースのアプリケーションのセキュリティを分析する場合、*悪意のある JavaScript コードが正規のアプリケーション コードと同じ権限* を持っていることを認識することが重要です。すべての JavaScript アプリケーションは、ある程度このリスクにさらされます。
Applications might obtain OAuth tokens that confer authorization necessary for them to function. In combination, this effectively gives compromised code the ability to use that authorization for malicious ends. Though the risk of attacker abuse of authorization is unavoidable, there are ways to limit the extent to which a compromised application can abuse that authorization. For instance, this access might be limited to times when the application is in active use, by limiting the type of tokens that might be obtained or by binding the tokens to the browser.
アプリケーションは、機能するために必要な承認を与える OAuth トークンを取得する場合があります。これを組み合わせると、侵害されたコードにその承認を悪意のある目的で使用する機能が効果的に与えられます。攻撃者による認可の悪用のリスクは避けられませんが、侵害されたアプリケーションによる認可の悪用の範囲を制限する方法はあります。たとえば、取得できるトークンの種類を制限したり、トークンをブラウザにバインドしたりすることで、このアクセスをアプリケーションがアクティブに使用されている時間に限定することができます。
When the legitimate application code can access variables or call functions, the malicious JavaScript code can do exactly the same. Furthermore, the malicious JavaScript code can tamper with the regular execution flow of the application, as well as with any application-level defenses, since they are typically controlled from within the application. For example, the attacker can remove or override event listeners, modify the behavior of built-in functions (prototype pollution), and stop pages in frames from loading.
正規のアプリケーション コードが変数にアクセスしたり、関数を呼び出したりできる場合、悪意のある JavaScript コードもまったく同じことを行う可能性があります。さらに、悪意のある JavaScript コードは、通常はアプリケーション内から制御されるため、アプリケーションの通常の実行フローやアプリケーション レベルの防御を改ざんする可能性があります。たとえば、攻撃者はイベント リスナーを削除またはオーバーライドしたり、組み込み関数の動作を変更したり (プロトタイプ汚染)、フレーム内のページの読み込みを停止したりすることができます。
The impact of malicious JavaScript on browser-based applications is a widely studied and well-understood topic. However, the concrete impact of malicious JavaScript on browser-based applications acting as an OAuth client is quite unique, since the malicious JavaScript can now impact the interactions during an OAuth flow. This section explores the threats malicious JavaScript code poses to a browser-based application with the responsibilities of an OAuth client. Section 5.1 discusses a few scenarios that attackers can use once they have found a way to run malicious JavaScript code. These scenarios paint a clear picture of the true power of the attacker, which goes way beyond simple token exfiltration. Section 5.2 analyzes the impact of these attack scenarios on the OAuth client.
ブラウザベースのアプリケーションに対する悪意のある JavaScript の影響は、広く研究されており、よく理解されているトピックです。ただし、悪意のある JavaScript が OAuth フロー中の対話に影響を与える可能性があるため、OAuth クライアントとして機能するブラウザベースのアプリケーションに対する悪意のある JavaScript の具体的な影響は非常に独特です。このセクションでは、OAuth クライアントの役割を持つ、悪意のある JavaScript コードがブラウザベースのアプリケーションにもたらす脅威について説明します。セクション 5.1 では、悪意のある JavaScript コードを実行する方法を見つけた攻撃者が使用できるいくつかのシナリオについて説明します。これらのシナリオは、単純なトークンの漏洩をはるかに超えた、攻撃者の真の力を明確に示しています。セクション 5.2 では、OAuth クライアントに対するこれらの攻撃シナリオの影響を分析します。
The remainder of this specification will refer back to these attack scenarios and consequences to analyze the security properties of the different architectural patterns.
この仕様の残りの部分では、さまざまなアーキテクチャ パターンのセキュリティ特性を分析するために、これらの攻撃シナリオとその結果を再度参照します。
This section presents several attack scenarios that an attacker can execute once they have found a vulnerability that allows the execution of malicious JavaScript code. The attack scenarios include trivial scenarios (Section 5.1.1) and elaborate scenarios (Section 5.1.3). Note that this enumeration is non-exhaustive, narrowly scoped to OAuth-specific features, and presented in no particular order.
このセクションでは、悪意のある JavaScript コードの実行を可能にする脆弱性を攻撃者が発見した場合に実行できるいくつかの攻撃シナリオを示します。攻撃シナリオには、簡単なシナリオ (セクション 5.1.1) と複雑なシナリオ (セクション 5.1.3) が含まれます。この列挙は網羅的なものではなく、OAuth 固有の機能に限定されており、特定の順序で示されていないことに注意してください。
The single-execution token theft scenario covers a simple token exfiltration attack, where the attacker obtains and exfiltrates the client's current tokens. This scenario consists of the following steps:
単一実行トークン盗難シナリオでは、攻撃者がクライアントの現在のトークンを取得して窃取する、単純なトークン引出し攻撃をカバーしています。このシナリオは次の手順で構成されます。
* Execute malicious JavaScript code
* 悪意のあるJavaScriptコードを実行する
* Obtain tokens from the application's preferred storage mechanism (Section 8)
* アプリケーションの優先ストレージメカニズムからトークンを取得する (セクション 8)
* Send the tokens to a server controlled by the attacker
* 攻撃者が制御するサーバーにトークンを送信する
* Store or abuse the stolen tokens
* 盗んだトークンを保管または悪用する
The recommended defensive strategy to decrease the risk associated with compromised access tokens is to reduce the scope and lifetime of the token. For refresh tokens, the use of refresh token rotation (as defined in Section 4.14.2 of [RFC9700]) offers a detection and correction mechanism. Sender-constrained tokens (Section 9.2) offer an additional layer of protection against stolen access tokens.
アクセス トークンの侵害に関連するリスクを軽減するために推奨される防御戦略は、トークンの範囲と有効期間を短縮することです。リフレッシュ トークンの場合、リフレッシュ トークン ローテーション ([RFC9700] のセクション 4.14.2 で定義) を使用することで、検出および修正メカニズムが提供されます。送信者制限トークン (セクション 9.2) は、盗まれたアクセス トークンに対する追加の保護層を提供します。
Note that this attack scenario is trivial and often used to illustrate the dangers of malicious JavaScript. When discussing the security of browser-based applications, it is crucial to avoid limiting the attacker's capabilities to the attack discussed in this scenario.
この攻撃シナリオは簡単なものであり、悪意のある JavaScript の危険性を説明するためによく使用されることに注意してください。ブラウザベースのアプリケーションのセキュリティについて議論する場合、攻撃者の能力をこのシナリオで説明した攻撃に限定しないようにすることが重要です。
The persistent token theft attack scenario is a more advanced variation on the single-execution token theft scenario (Section 5.1.1). Instead of immediately stealing tokens upon the execution of the malicious code, the attacker sets up the necessary handlers to steal the application's tokens on a continuous basis. This scenario consists of the following steps:
永続的トークン盗難攻撃シナリオは、単一実行トークン盗難シナリオ (セクション 5.1.1) のより高度なバリエーションです。攻撃者は、悪意のあるコードの実行時にすぐにトークンを盗むのではなく、アプリケーションのトークンを継続的に盗むために必要なハンドラーをセットアップします。このシナリオは次の手順で構成されます。
* Execute malicious JavaScript code
* 悪意のあるJavaScriptコードを実行する
* Set up a continuous token theft mechanism (e.g., on a 10-second time interval)
* 継続的なトークン盗難メカニズムを設定します (例: 10 秒間隔)
- Obtain tokens from the application's preferred storage mechanism (Section 8)
- アプリケーションの優先ストレージメカニズムからトークンを取得する (セクション 8)
- Send the tokens to a server controlled by the attacker
- 攻撃者が制御するサーバーにトークンを送信する
- Store the tokens
- トークンを保管する
* Wait until the opportune moment to abuse the latest version of the stolen tokens
* 盗まれたトークンの最新バージョンを悪用する適切な瞬間まで待ちます
The crucial difference in this scenario is that the attacker always has access to the latest tokens used by the application. This slight variation in the attack scenario already suffices to counter typical defenses against token theft, such as short lifetimes or refresh token rotation.
このシナリオの決定的な違いは、攻撃者がアプリケーションで使用される最新のトークンに常にアクセスできることです。攻撃シナリオにおけるこのわずかな変化は、短い有効期間やリフレッシュ トークンのローテーションなど、トークンの盗難に対する一般的な防御に対抗するにはすでに十分です。
For access tokens, the attacker now obtains the latest access token for as long as the user's browser is online. Refresh token rotation is not sufficient to prevent abuse of a refresh token. An attacker can easily ensure that the application will not use the latest refresh token. For example, the attacker could clear the application's tokens after stealing them, wait until the user closes the application, or wait until the user's browser goes offline. Since the application will not use the latest refresh token, there will be no detectable refresh token reuse, giving the attacker full control over the stolen refresh token.
アクセス トークンについては、ユーザーのブラウザがオンラインである限り、攻撃者は最新のアクセス トークンを取得するようになりました。リフレッシュ トークンのローテーションだけでは、リフレッシュ トークンの悪用を防ぐのに十分ではありません。攻撃者は、アプリケーションが最新のリフレッシュ トークンを使用しないことを簡単に確認できます。たとえば、攻撃者はアプリケーションのトークンを盗んだ後にクリアしたり、ユーザーがアプリケーションを閉じるまで待機したり、ユーザーのブラウザがオフラインになるまで待機したりする可能性があります。アプリケーションは最新のリフレッシュ トークンを使用しないため、検出可能なリフレッシュ トークンの再利用はなく、攻撃者は盗まれたリフレッシュ トークンを完全に制御できるようになります。
In the advanced acquisition and extraction of new tokens attack scenario, the attacker completely disregards any tokens that the application has already obtained. Instead, the attacker takes advantage of the ability to run malicious code that is associated with the application's origin. With that ability, the attacker can inject a hidden iframe and launch a silent Authorization Code flow. This silent flow will reuse the user's existing session with the authorization server and result in the issuing of a new, independent access token (and optionally refresh token). This scenario consists of the following steps:
新しいトークンの高度な取得と抽出の攻撃シナリオでは、攻撃者はアプリケーションがすでに取得しているトークンを完全に無視します。代わりに、攻撃者はアプリケーションの生成元に関連付けられた悪意のあるコードを実行できる機能を利用します。この機能を使用すると、攻撃者は非表示の iframe を挿入し、サイレントな認証コード フローを開始することができます。このサイレント フローは、認可サーバーとのユーザーの既存のセッションを再利用し、その結果、新しい独立したアクセス トークン (およびオプションでリフレッシュ トークン) が発行されます。このシナリオは次の手順で構成されます。
* Execute malicious JavaScript code
* 悪意のあるJavaScriptコードを実行する
* Set up a handler to obtain the authorization code from the iframe (e.g., by monitoring the frame's URL or via Web Messaging [WebMessaging])
* iframe から認証コードを取得するハンドラーを設定します (例: フレームの URL を監視するか、Web メッセージング [WebMessaging] 経由)。
* Insert a hidden iframe into the page and initialize it with an authorization request. The authorization request in the iframe will occur within the user's session and, if the session is still active, result in the issuing of an authorization code. Note that this step relies on the authorization server supporting silent frame-based flows, as discussed in the last paragraph of this scenario.
* 非表示の iframe をページに挿入し、承認リクエストで初期化します。iframe 内の認可リクエストはユーザーのセッション内で発生し、セッションがまだアクティブな場合は認可コードが発行されます。このシナリオの最後の段落で説明したように、この手順はサイレント フレームベースのフローをサポートする認可サーバーに依存していることに注意してください。
* Extract the authorization code from the iframe using the previously installed handler
* 以前にインストールしたハンドラーを使用して、iframe から認証コードを抽出します。
* Send the authorization code to a server controlled by the attacker
* 攻撃者が制御するサーバーに認証コードを送信する
* Exchange the authorization code for a new set of tokens
* 認証コードを新しいトークンのセットと交換します。
* Abuse the stolen tokens
* 盗んだトークンを悪用する
The most important takeaway from this scenario is that it runs a new OAuth flow instead of focusing on stealing existing tokens. In essence, even if the application finds a token storage mechanism that is able to completely isolate the stored tokens from the attacker, the attacker will still be able to request a new set of tokens. Note that because the attacker controls the application in the browser, the attacker's Authorization Code flow is indistinguishable from a legitimate Authorization Code flow.
このシナリオから得られる最も重要な点は、既存のトークンを盗むことに重点を置くのではなく、新しい OAuth フローを実行するということです。基本的に、アプリケーションが、保存されたトークンを攻撃者から完全に隔離できるトークン保存メカニズムを見つけたとしても、攻撃者は依然として新しいトークンのセットを要求できます。攻撃者はブラウザでアプリケーションを制御するため、攻撃者の認可コード フローは正規の認可コード フローと区別できないことに注意してください。
This attack scenario is possible because the security of public browser-based OAuth clients relies entirely on the redirect URI and application's origin. When the attacker executes malicious JavaScript code in the application's origin, they gain the capability to inspect same-origin frames. As a result, the attacker's code running in the main execution context can inspect the redirect URI loaded in the same-origin frame to extract the authorization code.
この攻撃シナリオが可能になるのは、パブリック ブラウザベースの OAuth クライアントのセキュリティがリダイレクト URI とアプリケーションのオリジンに完全に依存しているためです。攻撃者がアプリケーションのオリジンで悪意のある JavaScript コードを実行すると、同一オリジンのフレームを検査できるようになります。その結果、メイン実行コンテキストで実行されている攻撃者のコードは、同一生成元フレームにロードされたリダイレクト URI を検査して、認可コードを抽出する可能性があります。
There are no practical security mechanisms for frontend applications that counter this attack scenario. Short access token lifetimes and refresh token rotation are ineffective, since the attacker has a fresh, independent set of tokens. Advanced security mechanism, such as DPoP [RFC9449], are equally ineffective, since the attacker can use their own key pair to set up and use DPoP for the newly obtained tokens. Requiring user interaction with every Authorization Code flow would effectively stop the automatic silent issuance of new tokens, but this would significantly impact widely established patterns, such as bootstrapping an application on its first page load or single sign-on across multiple related applications, and is not a practical measure.
この攻撃シナリオに対抗するフロントエンド アプリケーション用の実用的なセキュリティ メカニズムはありません。攻撃者は新しい独立したトークンのセットを持っているため、短いアクセス トークンの有効期間とリフレッシュ トークンのローテーションは効果がありません。DPoP [RFC9449] などの高度なセキュリティ メカニズムも同様に効果がありません。攻撃者が独自のキー ペアを使用して、新しく取得したトークンに対して DPoP をセットアップして使用できるからです。すべての認可コード フローでユーザーの操作を要求すると、新しいトークンの自動的なサイレント発行が効果的に停止されますが、これは、最初のページ読み込み時のアプリケーションのブートストラップや複数の関連アプリケーション間でのシングル サインオンなど、広く確立されているパターンに大きな影響を与えるため、現実的な対策ではありません。
This attack scenario involves the attacker sending requests to the OAuth resource server directly from within the OAuth client application running in the user's browser. In this scenario, there is no need for the attacker to abuse the application to obtain tokens, since the browser will include its own cookies or tokens in the request. The requests sent by the attacker to the resource server are indistinguishable from requests sent by the legitimate application, since the attacker is running code in the same context as the legitimate application. This scenario consists of the following steps:
この攻撃シナリオには、攻撃者がユーザーのブラウザで実行されている OAuth クライアント アプリケーション内から OAuth リソース サーバーにリクエストを直接送信することが含まれます。このシナリオでは、ブラウザーがリクエストに独自の Cookie またはトークンを含めるため、攻撃者がアプリケーションを悪用してトークンを取得する必要はありません。攻撃者は正規のアプリケーションと同じコンテキストでコードを実行しているため、攻撃者によってリソース サーバーに送信されたリクエストは、正規のアプリケーションによって送信されたリクエストと区別できません。このシナリオは次の手順で構成されます。
* Execute malicious JavaScript code
* 悪意のあるJavaScriptコードを実行する
* Send a request to a resource server and process the response
* リソースサーバーにリクエストを送信し、レスポンスを処理します。
To authorize the requests to the resource server, the attacker simply mimics the behavior of the client application. For example, when a client application programmatically attaches an access token to outgoing requests, the attacker does the same. Should the client application rely on an external component to augment the request with the proper access token, then this external component will also augment the attacker's request.
リソース サーバーへのリクエストを承認するために、攻撃者はクライアント アプリケーションの動作を模倣するだけです。たとえば、クライアント アプリケーションが発信リクエストにアクセス トークンをプログラムで添付すると、攻撃者も同じことを行います。クライアント アプリケーションが適切なアクセス トークンでリクエストを拡張するために外部コンポーネントに依存する場合、この外部コンポーネントは攻撃者のリクエストも拡張します。
This attack pattern is well known and also occurs with server-side web applications using HttpOnly session cookies. It is commonly accepted that this scenario cannot be stopped or prevented by application-level security measures. For example, DPoP [RFC9449] explicitly considers this attack scenario to be out of scope.
この攻撃パターンはよく知られており、HttpOnly セッション Cookie を使用するサーバー側 Web アプリケーションでも発生します。このシナリオは、アプリケーション レベルのセキュリティ対策では阻止または防止できないことが一般的に受け入れられています。たとえば、DPoP [RFC9449] では、この攻撃シナリオは範囲外であると明示的にみなされています。
Successful execution of an attack scenario can result in the theft of access tokens and refresh tokens or in the ability to hijack the client application running in the user's browser. Each of these consequences is relevant for browser-based OAuth clients. They are discussed below in decreasing order of severity.
攻撃シナリオの実行に成功すると、アクセス トークンやリフレッシュ トークンが盗まれたり、ユーザーのブラウザで実行されているクライアント アプリケーションがハイジャックされたりする可能性があります。これらの結果はそれぞれ、ブラウザベースの OAuth クライアントに関係します。以下では、重大度の降順に説明します。
When the attacker obtains a valid refresh token from a browser-based OAuth client, they can abuse the refresh token by running a Refresh Token grant with the authorization server. The response of the Refresh Token grant contains an access token, which gives the attacker the ability to access protected resources (see Section 5.2.2). In essence, abusing a stolen refresh token enables long-term impersonation of the legitimate client application in requests to resource servers.
攻撃者がブラウザベースの OAuth クライアントから有効なリフレッシュ トークンを取得すると、認可サーバーでリフレッシュ トークン付与を実行することにより、そのリフレッシュ トークンを悪用する可能性があります。リフレッシュ トークン付与の応答にはアクセス トークンが含まれており、これにより攻撃者は保護されたリソースにアクセスできるようになります (セクション 5.2.2 を参照)。基本的に、盗まれたリフレッシュ トークンを悪用すると、リソース サーバーへのリクエストで正規のクライアント アプリケーションの長期にわたる偽装が可能になります。
The attack is only stopped when the authorization server refuses a refresh token because it has expired or rotated or when the refresh token is revoked. In a typical browser-based OAuth client, it is not uncommon for a refresh token to remain valid for multiple hours or even days.
攻撃は、有効期限が切れているかローテーションされているために認可サーバーがリフレッシュ トークンを拒否した場合、またはリフレッシュ トークンが取り消された場合にのみ停止されます。一般的なブラウザベースの OAuth クライアントでは、リフレッシュ トークンが数時間、場合によっては数日間有効なままになることも珍しくありません。
If the attacker obtains a valid access token, they gain the ability to impersonate the legitimate client application in a request to a resource server. Concretely, possession of an access token allows the attacker to send arbitrary requests to any resource server that accepts the valid access token. In essence, abusing a stolen access token enables short-term impersonation of the legitimate client application to resource servers.
攻撃者が有効なアクセス トークンを取得すると、リソース サーバーへのリクエストで正規のクライアント アプリケーションになりすますことができます。具体的には、アクセス トークンを所有すると、攻撃者は有効なアクセス トークンを受け入れるリソース サーバーに任意のリクエストを送信することができます。基本的に、盗まれたアクセス トークンを悪用すると、正当なクライアント アプリケーションがリソース サーバーに対して短期的になりすますことが可能になります。
The attack ends when the access token expires or when a token is revoked with the authorization server. In a typical browser-based OAuth client, access token lifetimes can be quite short, ranging from minutes to hours.
アクセス トークンの有効期限が切れるか、トークンが認可サーバーによって取り消されると、攻撃は終了します。一般的なブラウザベースの OAuth クライアントでは、アクセス トークンの有効期間は数分から数時間と非常に短い場合があります。
Note that the possession of the access token allows its unrestricted use by the attacker. The attacker can send arbitrary requests to resource servers using any HTTP method, destination URL, header values, or body.
アクセス トークンを所有すると、攻撃者による無制限の使用が許可されることに注意してください。攻撃者は、任意の HTTP メソッド、宛先 URL、ヘッダー値、または本文を使用して、リソース サーバーに任意のリクエストを送信できます。
The application can use DPoP to ensure its access tokens are bound to non-exportable keys held by the browser. In that case, it becomes significantly harder for the attacker to abuse stolen access tokens. More specifically, with DPoP, the attacker can only abuse stolen application tokens by carrying out an online attack where the proofs are calculated in the user's browser. This attack is described in detail in Section 11.4 of [RFC9449]. However, when the attacker obtains a fresh access token (and optionally refresh token), as described in Section 5.1.3, they can set up DPoP for these tokens using an attacker-controlled key pair. In that case, the attacker is again free to abuse this newly obtained access token without restrictions.
アプリケーションは DPoP を使用して、アクセス トークンがブラウザーが保持するエクスポート不可能なキーにバインドされていることを確認できます。その場合、攻撃者が盗んだアクセス トークンを悪用することが大幅に困難になります。より具体的には、DPoP を使用すると、攻撃者はユーザーのブラウザで証明が計算されるオンライン攻撃を実行することによってのみ、盗んだアプリケーション トークンを悪用できます。この攻撃については、[RFC9449] のセクション 11.4 で詳しく説明されています。ただし、セクション 5.1.3 で説明されているように、攻撃者が新しいアクセス トークン (およびオプションでリフレッシュ トークン) を取得すると、攻撃者が制御するキー ペアを使用してこれらのトークンに DPoP を設定できます。その場合、攻撃者は再びこの新しく取得したアクセス トークンを制限なく自由に悪用できます。
When stealing tokens is not possible or desirable, the attacker can also choose to hijack the OAuth client application running in the user's browser. This effectively allows the attacker to perform any operations that the legitimate client application can perform. Examples include inspecting data on the page, modifying the page, and sending requests to backend systems. Alternatively, the attacker can also abuse their access to the application to launch additional attacks, such as tricking the client into acting on behalf of the attacker using an attack such as session fixation [SessionFixation].
トークンを盗むことが不可能または望ましくない場合、攻撃者はユーザーのブラウザで実行されている OAuth クライアント アプリケーションをハイジャックすることもできます。これにより、攻撃者は、正規のクライアント アプリケーションが実行できるあらゆる操作を実行できるようになります。例には、ページ上のデータの検査、ページの変更、バックエンド システムへのリクエストの送信などが含まれます。あるいは、攻撃者はアプリケーションへのアクセスを悪用して、セッション固定 [SessionFixation] などの攻撃を使用してクライアントをだまして攻撃者に代わって動作させるなど、追加の攻撃を開始することもできます。
Note that client hijacking is less powerful than directly abusing stolen user tokens. In a client-hijacking scenario, the attacker cannot directly control the tokens and is restricted by the security policies enforced on the client application. For example, a resource server running on admin.example.org can be configured with a CORS policy that rejects requests coming from a client running on web.example.org. Even if the access token used by the client would be accepted by the resource server, the resource server's strict CORS configuration would not allow such a request. A resource server without such a strict CORS policy can still be subject to adversarial requests coming from the compromised client application.
クライアントのハイジャックは、盗まれたユーザー トークンを直接悪用するほど強力ではないことに注意してください。クライアント ハイジャックのシナリオでは、攻撃者はトークンを直接制御できず、クライアント アプリケーションに適用されているセキュリティ ポリシーによって制限されます。たとえば、admin.example.org で実行されているリソース サーバーは、web.example.org で実行されているクライアントからのリクエストを拒否する CORS ポリシーを使用して構成できます。クライアントが使用するアクセス トークンがリソース サーバーによって受け入れられる場合でも、リソース サーバーの厳密な CORS 構成ではそのような要求は許可されません。このような厳格な CORS ポリシーを持たないリソース サーバーは、侵害されたクライアント アプリケーションからの敵対的なリクエストの影響を受ける可能性があります。
There are three main architectural patterns available when building browser-based applications that rely on OAuth for accessing protected resources:
保護されたリソースへのアクセスに OAuth に依存するブラウザベースのアプリケーションを構築する場合、次の 3 つの主なアーキテクチャ パターンが利用できます。
* A browser-based application that relies on a backend component for handling OAuth responsibilities and forwards all requests through the backend component ("Backend for Frontend" or "BFF")
* OAuth の役割を処理するためにバックエンド コンポーネントに依存し、すべてのリクエストをバックエンド コンポーネント (「フロントエンド用バックエンド」または「BFF」) 経由で転送するブラウザベースのアプリケーション
* A browser-based application that relies on a backend component for handling OAuth responsibilities but calls resource servers directly using the access token (token-mediating backend)
* OAuth の役割を処理するためにバックエンド コンポーネントに依存しますが、アクセス トークン (トークン仲介バックエンド) を使用してリソース サーバーを直接呼び出すブラウザベースのアプリケーション
* A browser-based application acting as the client, handling all OAuth responsibilities in the browser (browser-based OAuth client)
* クライアントとして機能し、ブラウザですべての OAuth の役割を処理するブラウザベースのアプリケーション (ブラウザベースの OAuth クライアント)
Each of these architectural patterns offers a different trade-off between security and simplicity. The patterns in this section are presented in decreasing order of security.
これらのアーキテクチャ パターンはそれぞれ、セキュリティとシンプルさの間で異なるトレードオフを提供します。このセクションのパターンは、セキュリティの降順に示されています。
This section describes the architecture of a browser-based application that relies on a backend component to handle all OAuth responsibilities and API interactions. The BFF has three core responsibilities:
このセクションでは、すべての OAuth の役割と API 対話を処理するバックエンド コンポーネントに依存するブラウザベースのアプリケーションのアーキテクチャについて説明します。BFF には 3 つの主要な責任があります。
1. The BFF interacts with the authorization server as a confidential OAuth client (as defined in Section 2.1 of [RFC6749]).
1. BFF は、([RFC6749] のセクション 2.1 で定義されている) 機密 OAuth クライアントとして認可サーバーと対話します。
2. The BFF manages OAuth access and refresh tokens in the context of a cookie-based session, avoiding the direct exposure of any tokens to the browser-based application.
2. BFF は、Cookie ベースのセッションのコンテキストで OAuth アクセスとリフレッシュ トークンを管理し、ブラウザベースのアプリケーションへのトークンの直接公開を回避します。
3. The BFF forwards all requests to a resource server, augmenting them with the correct access token before forwarding them to the resource server.
3. BFF はすべてのリクエストをリソース サーバーに転送し、リソース サーバーに転送する前に正しいアクセス トークンを追加します。
In this architecture, the BFF runs as a server-side component, but it is a component of the frontend application. To avoid confusion with other architectural concepts, such as API gateways and reverse proxies, it is important to keep in mind that the BFF becomes the OAuth client for the frontend application.
このアーキテクチャでは、BFF はサーバー側コンポーネントとして実行されますが、フロントエンド アプリケーションのコンポーネントです。API ゲートウェイやリバース プロキシなどの他のアーキテクチャ概念との混同を避けるために、BFF がフロントエンド アプリケーションの OAuth クライアントになることに留意することが重要です。
If an attacker is able to execute malicious code within the browser-based application, the application architecture is able to withstand most of the attack scenarios discussed before. Since tokens are only available to the BFF, there are no tokens available to extract from the browser (see "Single-Execution Token Theft" (Section 5.1.1) and "Persistent Token Theft" (Section 5.1.2)). The BFF is a confidential client, which prevents the attacker from running a new flow within the browser (see "Acquisition and Extraction of New Tokens" (Section 5.1.3)). Since the malicious browser-based code still runs within the application's origin, the attacker is able to send requests to the BFF from within the user's browser (see "Proxying Requests via the User's Browser" (Section 5.1.4)). Note that the use of HttpOnly cookies prevents the attacker from directly accessing the session state, which prevents the escalation from client hijacking to session hijacking.
攻撃者がブラウザベースのアプリケーション内で悪意のあるコードを実行できる場合、アプリケーション アーキテクチャは前述のほとんどの攻撃シナリオに耐えることができます。トークンはBFFのみが利用できるため、ブラウザから抽出できるトークンはありません(「単一実行トークンの盗難」(セクション5.1.1)および「永続的トークンの盗難」(セクション5.1.2)を参照)。BFF は機密クライアントであり、攻撃者がブラウザ内で新しいフローを実行するのを防ぎます (「新しいトークンの取得と抽出」 (セクション 5.1.3) を参照)。悪意のあるブラウザベースのコードはアプリケーションのオリジン内で引き続き実行されるため、攻撃者はユーザーのブラウザ内から BFF にリクエストを送信できます (「ユーザーのブラウザを介したリクエストのプロキシ」 (セクション 5.1.4) を参照)。HttpOnly Cookie を使用すると、攻撃者がセッション状態に直接アクセスできなくなり、クライアント ハイジャックからセッション ハイジャックへのエスカレーションが防止されることに注意してください。
+---------------+ +----------+ +----------+
| | | | | |
| Authorization | | Token | | Resource |
| Endpoint | | Endpoint | | Server |
| | | | | |
+---------------+ +----------+ +----------+
^ ^ ^
| (F)| (K)|
| v v
|
| +------------------------------+
| | |
| | Backend for Frontend (BFF) |
(D)| | |
| +------------------------------+
|
| ^ ^ ^ + ^ +
| (B,I)| (C)| (E)| (G)| (J)| |(L)
v v v + v + v
+-----------------+ +-----------------------------------------+
| | (A,H) | |
| Static Web Host | +-----> | Browser |
| | | |
+-----------------+ +-----------------------------------------+
Figure 1: OAuth 2.0 BFF Pattern
図 1: OAuth 2.0 BFF パターン
In this architecture, the browser code (typically JavaScript) is first loaded from a static web host into the browser (A), and the application then runs in the browser. The application checks with the BFF to identify if there is an active session by calling a "check session" API endpoint (B). If an active session is found, the application resumes its authenticated state and skips forward to (J).
このアーキテクチャでは、まずブラウザ コード (通常は JavaScript) が静的 Web ホストからブラウザにロードされ (A)、次にアプリケーションがブラウザ内で実行されます。アプリケーションは、「セッションチェック」API エンドポイント (B) を呼び出して、BFF をチェックしてアクティブなセッションがあるかどうかを識別します。アクティブなセッションが見つかった場合、アプリケーションは認証状態を再開し、(J) に進みます。
When no active session is found, the browser-based application triggers a navigation to the BFF (C) to initiate the Authorization Code flow with the PKCE extension (described in Section 6.1.3.1), to which the BFF responds by redirecting the browser to the authorization endpoint (D). When the user is redirected back, the browser delivers the authorization code to the BFF (E), where the BFF can then exchange it for tokens at the token endpoint (F) using its client credentials and PKCE code verifier.
アクティブなセッションが見つからない場合、ブラウザベースのアプリケーションは BFF (C) へのナビゲーションをトリガーし、PKCE 拡張機能 (セクション 6.1.3.1 で説明) を使用して認可コード フローを開始します。これに対して、BFF はブラウザを認可エンドポイント (D) にリダイレクトすることで応答します。ユーザーがリダイレクトされて戻されると、ブラウザーは認証コードを BFF (E) に配信し、BFF はクライアント資格情報と PKCE コード検証ツールを使用して、トークン エンドポイント (F) でそのコードをトークンと交換できます。
The BFF associates the obtained tokens with the user's session (see Section 6.1.2.3) and sets a cookie in the response to keep track of this session (G). At this point, the redirect-based Authorization Code flow has been completed, so the BFF can hand control back to the frontend application. It does so by including a redirect in the response (G), triggering the browser to fetch the frontend from the server (H). Note that step (H) is identical to step (A), which likely means that the requested resources can be loaded from the browser's cache. When the frontend loads, it will check with the BFF for an existing session (I), allowing the application to resume its authenticated state.
BFF は、取得したトークンをユーザーのセッションに関連付け (セクション 6.1.2.3 を参照)、このセッションを追跡するために応答に Cookie を設定します (G)。この時点で、リダイレクト ベースの認証コード フローが完了しているため、BFF は制御をフロントエンド アプリケーションに戻すことができます。これは、応答 (G) にリダイレクトを含めることによって行われ、ブラウザーがサーバーからフロントエンドを取得するようにトリガーされます (H)。ステップ (H) はステップ (A) と同じであることに注意してください。これはおそらく、要求されたリソースをブラウザーのキャッシュからロードできることを意味します。フロントエンドがロードされると、BFF で既存のセッション (I) を確認し、アプリケーションが認証された状態を再開できるようにします。
When the application in the browser wants to make a request to the resource server, it sends a request to the corresponding endpoint on the BFF (J). This request will include the cookie set in (G), allowing the BFF to obtain the proper tokens for this user's session. The BFF removes the cookie from the request, attaches the user's access token to the request, and forwards it to the actual resource server (K). The BFF then forwards the response back to the browser-based application (L).
ブラウザ内のアプリケーションがリソース サーバーにリクエストを送信する場合、BFF 上の対応するエンドポイントにリクエストを送信します (J)。このリクエストには (G) で設定された Cookie が含まれるため、BFF はこのユーザーのセッションに適切なトークンを取得できます。BFF はリクエストから Cookie を削除し、ユーザーのアクセス トークンをリクエストに添付して、実際のリソース サーバー (K) に転送します。次に、BFF は応答をブラウザベースのアプリケーション (L) に転送します。
The BFF provides a set of endpoints that are crucial to implement the interactions between the browser-based application and the BFF. This section discusses these endpoints in more detail to clarify their purpose and use cases.
BFF は、ブラウザベースのアプリケーションと BFF の間の対話を実装するために重要な一連のエンドポイントを提供します。このセクションでは、これらのエンドポイントについて詳しく説明し、その目的と使用例を明確にします。
The "check session" endpoint ((B) and (I) in Figure 1) is an API endpoint called by the browser-based application. The request will carry session information when available, allowing the BFF to check for an active session. The response should indicate to the browser-based application whether the session is active. Additionally, the BFF can include other information, such as identity information about the authenticated user.
「チェックセッション」エンドポイント (図 1 の (B) および (I)) は、ブラウザベースのアプリケーションによって呼び出される API エンドポイントです。リクエストにはセッション情報が含まれている場合はその情報が含まれるため、BFF はアクティブなセッションを確認できます。応答は、セッションがアクティブであるかどうかをブラウザベースのアプリケーションに示す必要があります。さらに、BFF には、認証されたユーザーに関する ID 情報などの他の情報を含めることができます。
The endpoint that initiates the Authorization Code flow (C) is contacted by the browser through a navigation. When the application detects an unauthenticated state after checking the session (B), it can navigate the browser to this endpoint. Doing so allows the BFF to respond with a redirect, which takes the browser to the authorization server. The endpoint to initiate this flow is typically included as the "login" endpoint by libraries that support OAuth 2.0 for confidential clients running on a web server. Note that it is also possible for the BFF to initiate the Authorization Code flow in (B) when it detects the absence of an active session. In that case, the BFF would return the authorization URI in the response and expect the application to trigger a navigation event with this URI. However, this scenario requires a custom implementation and makes it harder to use standard OAuth libraries.
認証コード フロー (C) を開始するエンドポイントは、ナビゲーションを通じてブラウザーによって接続されます。アプリケーションがセッションをチェックした後に未認証状態を検出すると (B)、ブラウザーをこのエンドポイントに移動できます。そうすることで、BFF がリダイレクトで応答できるようになり、ブラウザーが認可サーバーに移動します。このフローを開始するエンドポイントは、通常、Web サーバー上で実行されている機密クライアントの OAuth 2.0 をサポートするライブラリに「ログイン」エンドポイントとして組み込まれています。BFF は、アクティブなセッションの不在を検出したときに (B) の認証コード フローを開始することも可能であることに注意してください。その場合、BFF は応答で認証 URI を返し、アプリケーションがこの URI でナビゲーション イベントをトリガーすることを期待します。ただし、このシナリオではカスタム実装が必要であり、標準の OAuth ライブラリの使用が困難になります。
The endpoint that receives the authorization code (E) is called by a navigation event from within the browser. At this point, the application is not loaded and not in a position to handle the redirect. Similar to the initiation of the flow, the endpoint to handle the redirect is offered by standard OAuth libraries. The BFF can respond to this request with a redirect that triggers the browser to load the application.
認証コード (E) を受信するエンドポイントは、ブラウザー内からのナビゲーション イベントによって呼び出されます。この時点では、アプリケーションはロードされておらず、リダイレクトを処理できる状態にもありません。フローの開始と同様に、リダイレクトを処理するエンドポイントは標準の OAuth ライブラリによって提供されます。BFF は、ブラウザーによるアプリケーションのロードをトリガーするリダイレクトでこのリクエストに応答できます。
Finally, the BFF can also offer a "logout" endpoint to the application, which is not depicted in Figure 1. The exact behavior of the logout endpoint depends on the application requirements. Note that standard OAuth libraries typically also offer an implementation of the "logout" endpoint.
最後に、BFF はアプリケーションに「ログアウト」エンドポイントを提供することもできますが、これは図 1 には示されていません。ログアウト エンドポイントの正確な動作は、アプリケーションの要件によって異なります。標準の OAuth ライブラリは通常、「ログアウト」エンドポイントの実装も提供していることに注意してください。
When using refresh tokens, as described in Section 4.14 of [RFC9700], the BFF obtains the refresh token (F) and associates it with the user's session.
[RFC9700] のセクション 4.14 で説明されているように、リフレッシュ トークンを使用する場合、BFF はリフレッシュ トークン (F) を取得し、それをユーザーのセッションに関連付けます。
If the BFF notices that the user's access token has expired and the BFF has a refresh token, it can use the refresh token to obtain a fresh access token. Since the BFF OAuth client is a confidential client, it will use client authentication on the refresh token request. Typically, the BFF performs these steps inline when handling an API call from the frontend. In that case, these steps, which are not explicitly shown in Figure 1, would occur between (J) and (K). BFFs that keep all token information available on the server side can also request fresh access tokens when they observe a token expiration event to increase the performance of API requests.
ユーザーのアクセス トークンの有効期限が切れており、BFF がリフレッシュ トークンを持っていることに BFF が気付いた場合、BFF はそのリフレッシュ トークンを使用して新しいアクセス トークンを取得できます。BFF OAuth クライアントは機密クライアントであるため、リフレッシュ トークン リクエストでクライアント認証を使用します。通常、BFF はフロントエンドからの API 呼び出しを処理するときにこれらの手順をインラインで実行します。その場合、これらのステップは、図 1 には明示的に示されていませんが、(J) と (K) の間で発生します。サーバー側ですべてのトークン情報を利用可能な状態に保つ BFF は、トークンの有効期限イベントを観察したときに、API リクエストのパフォーマンスを向上させるために新しいアクセス トークンをリクエストすることもできます。
When the refresh token expires, there is no way to obtain a valid access token without running an entirely new Authorization Code flow. Therefore, it makes sense to configure the lifetime of the cookie-based session managed by the BFF to be equal to the maximum lifetime of the refresh token. Additionally, when the BFF learns that a refresh token for an active session is no longer valid, it also makes sense to invalidate the session.
リフレッシュ トークンの有効期限が切れると、まったく新しい認証コード フローを実行する以外に有効なアクセス トークンを取得する方法はありません。したがって、BFF によって管理される Cookie ベースのセッションの有効期間を、リフレッシュ トークンの最大有効期間と等しくなるように構成することが合理的です。さらに、アクティブなセッションのリフレッシュ トークンが有効でなくなったことを BFF が認識した場合、セッションを無効にすることも理にかなっています。
The BFF relies on browser cookies [RFC6265bis] to keep track of the user's session, which is used to access the user's tokens. Cookie-based sessions, both server-side and client-side, have some downsides.
BFF はブラウザ Cookie [RFC6265bis] に依存して、ユーザーのトークンにアクセスするために使用されるユーザーのセッションを追跡します。Cookie ベースのセッションには、サーバー側とクライアント側の両方にいくつかの欠点があります。
Server-side sessions expose only a session identifier and keep all data on the server. Doing so ensures a great level of control over active sessions, along with the possibility to revoke any session at will. The downside of this approach is the impact on scalability, requiring solutions such as "sticky sessions" or "session replication". Given these downsides, using server-side sessions with a BFF is only recommended in small-scale scenarios.
サーバー側セッションはセッション識別子のみを公開し、すべてのデータをサーバー上に保持します。そうすることで、アクティブなセッションを高度に制御できるとともに、任意のセッションを自由に取り消すことが可能になります。このアプローチの欠点は、スケーラビリティへの影響であり、「スティッキー セッション」や「セッション レプリケーション」などのソリューションが必要になります。これらの欠点を考慮すると、BFF とのサーバー側セッションの使用は、小規模なシナリオでのみ推奨されます。
Client-side sessions push all data to the browser in a signed, and optionally encrypted, object. This pattern absolves the server of keeping track of any session data, but it severely limits control over active sessions and makes it difficult to handle session revocation. However, when client-side sessions are used in the context of a BFF, these properties change significantly. Since the cookie-based session is only used to obtain a user's tokens, all control and revocation properties follow from the use of access tokens and refresh tokens. It suffices to revoke the user's access token and/or refresh token to prevent ongoing access to protected resources, without the need to explicitly invalidate the cookie-based session.
クライアント側セッションは、すべてのデータを署名済みのオブジェクト (オプションで暗号化されたオブジェクト) でブラウザにプッシュします。このパターンでは、サーバーはセッション データを追跡する必要がなくなりますが、アクティブなセッションの制御が大幅に制限され、セッションの取り消しの処理が困難になります。ただし、クライアント側セッションが BFF のコンテキストで使用される場合、これらのプロパティは大幅に変化します。Cookie ベースのセッションはユーザーのトークンを取得するためにのみ使用されるため、すべての制御プロパティと取り消しプロパティはアクセス トークンとリフレッシュ トークンの使用に従います。Cookie ベースのセッションを明示的に無効にする必要はなく、ユーザーのアクセス トークンやリフレッシュ トークンを取り消して、保護されたリソースへの継続的なアクセスを防ぐだけで十分です。
Best practices to secure the session cookie are discussed in Section 6.1.3.2.
セッション Cookie を保護するためのベスト プラクティスについては、セクション 6.1.3.2 で説明します。
The OAuth flow used by this application architecture can be combined with OpenID Connect by including the necessary OpenID Connect scopes in the authorization request (C) (at least the scope openid as defined in Section 3.1.2.1 of [OpenID]). In that case, the BFF will receive an ID Token in (F). The BFF can associate the information from the ID Token with the user's session and provide it to the application in (B) or (I).
このアプリケーション アーキテクチャで使用される OAuth フローは、認可リクエスト (C) に必要な OpenID Connect スコープ (少なくとも [OpenID] のセクション 3.1.2.1 で定義されているスコープ openid) を含めることによって、OpenID Connect と組み合わせることができます。その場合、BFF は (F) で ID トークンを受け取ります。BFF は、ID トークンからの情報をユーザーのセッションに関連付け、(B) または (I) でアプリケーションに提供できます。
When needed, the BFF can use the access token associated with the user's session to make requests to the UserInfo endpoint.
必要に応じて、BFF はユーザーのセッションに関連付けられたアクセス トークンを使用して、UserInfo エンドポイントにリクエストを送信できます。
Serving the static JavaScript code is a separate responsibility from handling OAuth tokens and forwarding requests. In Figure 1, the BFF and static web host are shown as two separate entities. In real-world deployments, these components can be deployed as a single service (i.e., the BFF serving the static JavaScript code), as two separate services (i.e., a Content Delivery Network (CDN) and a BFF), or as two components in a single service (i.e., static hosting and serverless functions on a cloud platform).
静的 JavaScript コードの提供は、OAuth トークンの処理やリクエストの転送とは別の責任です。図 1 では、BFF と静的 Web ホストが 2 つの別個のエンティティとして示されています。実際の展開では、これらのコンポーネントは 1 つのサービス (つまり、静的 JavaScript コードを提供する BFF) として、2 つの別個のサービス (つまり、コンテンツ配信ネットワーク (CDN) と BFF) として、または 1 つのサービス内の 2 つのコンポーネント (つまり、クラウド プラットフォーム上の静的ホスティングとサーバーレス機能) として展開できます。
Note that it is possible to further customize this architecture to support specific scenarios. For example, an application relying on both internal and external resource servers can choose to host the internal resource server alongside the BFF. In that scenario, requests to the internal resource server are handled directly at the BFF, without the need to forward requests over the network. Authorization from the point of view of the resource server does not change, as the user's session is internally translated to the access token and its claims.
特定のシナリオをサポートするために、このアーキテクチャをさらにカスタマイズできることに注意してください。たとえば、内部リソース サーバーと外部リソース サーバーの両方に依存するアプリケーションは、BFF と並行して内部リソース サーバーをホストすることを選択できます。このシナリオでは、内部リソース サーバーへの要求は、ネットワーク経由で要求を転送することなく、BFF で直接処理されます。ユーザーのセッションは内部でアクセス トークンとそのクレームに変換されるため、リソース サーバーの観点から見た承認は変わりません。
The main benefit of using a BFF is the BFF's ability to act as a confidential client. Therefore, the BFF MUST act as a confidential client by establishing credentials with the authorization server. Furthermore, the BFF MUST use the OAuth 2.0 Authorization Code grant as described in Section 2.1.1 of [RFC9700] to initiate a request for an access token.
BFF を使用する主な利点は、BFF が機密クライアントとして機能できることです。したがって、BFF は、認可サーバーとの資格情報を確立することにより、機密クライアントとして機能しなければなりません。さらに、BFF は、[RFC9700] のセクション 2.1.1 で説明されているように、OAuth 2.0 認可コード許可を使用して、アクセス トークンの要求を開始しなければなりません (MUST)。
The BFF uses cookies to create a user session, which is directly associated with the user's tokens through either server-side or client-side session state. Given the sensitive nature of these cookies, they must be properly protected.
BFF は Cookie を使用してユーザー セッションを作成します。このセッションは、サーバー側またはクライアント側のセッション状態を通じてユーザーのトークンに直接関連付けられます。これらの Cookie は機密性が高いため、適切に保護する必要があります。
The following cookie security guidelines are relevant for this particular BFF architecture:
次の Cookie セキュリティ ガイドラインは、この特定の BFF アーキテクチャに関連します。
* The BFF MUST enable the Secure flag for its cookies.
* BFF は、Cookie の Secure フラグを有効にしなければなりません (MUST)。
* The BFF MUST enable the HttpOnly flag for its cookies.
* BFF は、Cookie の HttpOnly フラグを有効にしなければなりません (MUST)。
* The BFF SHOULD enable the SameSite=Strict flag for its cookies.
* BFF は、Cookie に対して SameSite=Strict フラグを有効にする必要があります (SHOULD)。
* The BFF SHOULD set its cookie path to /.
* BFF は cookie パスを / に設定すべきです (SHOULD)。
* The BFF SHOULD NOT set the Domain attribute for cookies.
* BFF は Cookie のドメイン属性を設定すべきではありません。
* The BFF SHOULD start the name of its cookie with a prefix indicating the cookie was set via HTTP, for example, by using the __Host-Http- prefix defined in [COOKIES].
* BFF は、Cookie の名前を、たとえば [COOKIES] で定義されている __Host-Http- 接頭辞を使用して、Cookie が HTTP 経由で設定されたことを示す接頭辞で始める必要があります (SHOULD)。
Note: In new deployments, all of the above requirements are likely to be straightforward to implement. The "SHOULD" items are not deemed as "MUST" items so that existing architectures can be compliant. The implications of these requirements are listed below.
注: 新しい展開では、上記の要件はすべて簡単に実装できる可能性があります。「SHOULD」項目は、既存のアーキテクチャが準拠できるように「MUST」項目とみなされません。これらの要件の影響を以下に示します。
These cookie security guidelines, combined with the use of HTTPS, help counter attacks that directly target a cookie-based session. Session hijacking is not possible due to the Secure and HttpOnly cookie flags. The __Host-Http- prefix prevents the cookie from being shared with subdomains, thereby countering subdomain-based session hijacking or session-fixation attacks. In a typical BFF deployment scenario, there is no reason to use more relaxed cookie security settings than the requirements listed above. Deviating from these settings requires proper motivation for the deployment scenario at hand.
これらの Cookie セキュリティ ガイドラインは、HTTPS の使用と組み合わせることで、Cookie ベースのセッションを直接標的とする攻撃に対抗するのに役立ちます。Secure Cookie フラグと HttpOnly Cookie フラグにより、セッション ハイジャックは不可能です。__Host-Http- プレフィックスは、Cookie がサブドメインと共有されるのを防ぎ、それによってサブドメインベースのセッション ハイジャックまたはセッション固定攻撃に対抗します。一般的な BFF 展開シナリオでは、上記の要件よりも緩和された Cookie セキュリティ設定を使用する理由はありません。これらの設定から逸脱するには、当面の展開シナリオに対する適切な動機が必要です。
Additionally, when using client-side sessions that contain access tokens (as opposed to server-side sessions where the tokens only live on the server), the BFF SHOULD encrypt its cookie contents. While the use of cookie encryption does not affect the security properties of the BFF pattern, it does ensure that tokens stored in cookies are never written to the user's local persistent storage in plaintext format. This security measure helps ensure the confidentiality of the tokens in case an attacker is able to read cookies from the hard drive. Such an attack can be launched through malware running on the victim's computer. Note that while encrypting the cookie contents prevents direct access to embedded tokens, it still allows the attacker to use the encrypted cookie in a session hijacking attack.
さらに、アクセス トークンを含むクライアント側セッションを使用する場合 (トークンがサーバー上にのみ存在するサーバー側セッションとは対照的に)、BFF はその Cookie コンテンツを暗号化する必要があります (SHOULD)。Cookie 暗号化の使用は BFF パターンのセキュリティ特性には影響しませんが、Cookie に保存されたトークンがユーザーのローカル永続ストレージに平文形式で書き込まれることがなくなります。このセキュリティ対策は、攻撃者がハード ドライブから Cookie を読み取ることができる場合に備えて、トークンの機密性を確保するのに役立ちます。このような攻撃は、被害者のコンピュータ上で実行されるマルウェアを通じて開始される可能性があります。Cookie の内容を暗号化すると、埋め込みトークンへの直接アクセスは防止されますが、攻撃者は暗号化された Cookie をセッション ハイジャック攻撃に使用することができます。
For further guidance on cookie security best practices, refer to the OWASP Cheat Sheet series [OWASPCheatSheet].
Cookie セキュリティのベスト プラクティスに関する詳細なガイダンスについては、OWASP Cheat Sheet シリーズ [OWASPCheatSheet] を参照してください。
The interactions between the browser-based application and the BFF rely on cookies for authentication and authorization. Similar to other cookie-based interactions, the BFF is required to account for Cross-Site Request Forgery (CSRF) attacks. A successful CSRF attack could allow the attacker's request to the BFF to trigger outgoing calls to a protected resource.
ブラウザベースのアプリケーションと BFF の間の対話は、認証と認可のために Cookie に依存します。他の Cookie ベースの対話と同様に、BFF はクロスサイト リクエスト フォージェリ (CSRF) 攻撃を考慮する必要があります。CSRF 攻撃が成功すると、BFF に対する攻撃者のリクエストにより、保護されたリソースへの発信呼び出しがトリガーされる可能性があります。
The BFF MUST implement a proper CSRF defense. The exact mechanism or combination of mechanisms depends on the exact domain where the BFF is deployed, as discussed below.
BFF は適切な CSRF 防御を実装しなければなりません。以下で説明するように、正確なメカニズムまたはメカニズムの組み合わせは、BFF が展開される正確なドメインによって異なります。
Configuring the cookies with the SameSite=Strict attribute (see Section 6.1.3.2) ensures that the BFF's cookies are only included on same-site requests and not on potentially malicious cross-site requests.
SameSite=Strict 属性 (セクション 6.1.3.2 を参照) を使用して Cookie を構成すると、BFF の Cookie が同じサイトのリクエストにのみ含まれ、悪意のある可能性のあるクロスサイトリクエストには含まれないことが保証されます。
This defense is adequate if the BFF is never considered to be same site with any other applications. However, it falls short when the BFF is hosted alongside other applications within the same site, defined as the eTLD+1 (see this definition in [Site] for more details).
BFF が他のアプリケーションと同じサイトであるとみなされることがない場合、この防御は十分です。ただし、BFF が同じサイト内の他のアプリケーションと一緒にホストされ、eTLD+1 として定義されている場合は不十分です (詳細については、[サイト] のこの定義を参照してください)。
For example, subdomains such as https://a.example.com and https://b.example.com are considered to be same site because they share the same site example.com. They are considered to be cross-origin because origins consist of the tuple <scheme, hostname, port>. As a result, a subdomain-takeover attack against b.example.com can enable CSRF attacks against the BFF of a.example.com. Note that these subdomain-based attacks follow the same pattern as CSRF attacks but with a cross-origin nature instead of a cross-site nature.
たとえば、https://a.example.com と https://b.example.com などのサブドメインは、同じサイト example.com を共有するため、同じサイトとみなされます。オリジンはタプル <scheme, hostname, port> で構成されているため、これらはクロスオリジンであるとみなされます。その結果、b.example.com に対するサブドメイン乗っ取り攻撃により、a.example.com の BFF に対する CSRF 攻撃が可能になる可能性があります。これらのサブドメインベースの攻撃は CSRF 攻撃と同じパターンに従いますが、クロスサイトの性質ではなくクロスオリジンの性質を持つことに注意してください。
The BFF can rely on CORS as a CSRF defense mechanism. CORS is a security mechanism implemented by browsers that restrict cross-origin requests, unless the server explicitly approves such a request by setting the proper CORS headers.
BFF は、CSRF 防御メカニズムとして CORS に依存できます。CORS はブラウザによって実装されるセキュリティ メカニズムであり、サーバーが適切な CORS ヘッダーを設定してそのようなリクエストを明示的に承認しない限り、クロスオリジン リクエストを制限します。
Browsers typically restrict cross-origin HTTP requests initiated from scripts. CORS can remove this restriction if the target server approves the request, which is checked through an initial "preflight" request. Unless the preflight response explicitly approves the request, the browser will refuse to send the full request.
通常、ブラウザはスクリプトから開始されるクロスオリジン HTTP リクエストを制限します。CORS は、ターゲット サーバーが最初の「プリフライト」要求によってチェックされる要求を承認した場合、この制限を削除できます。プリフライト応答がリクエストを明示的に承認しない限り、ブラウザはリクエスト全体の送信を拒否します。
Because of this property, the BFF can rely on CORS as a CSRF defense. When the attacker tries to launch a cross-origin request to the BFF from the user's browser, the BFF will not approve the request in the preflight response, causing the browser to block the actual request. Note that the attacker can always launch the request from their own machine, but then the request will not carry the user's cookies, so the attack will fail.
この特性により、BFF は CSRF 防御として CORS に依存できます。攻撃者がユーザーのブラウザから BFF へのクロスオリジン リクエストを開始しようとすると、BFF はプリフライト応答でリクエストを承認せず、ブラウザが実際のリクエストをブロックします。攻撃者はいつでも自分のマシンからリクエストを開始できますが、その場合リクエストにはユーザーの Cookie が含まれないため、攻撃は失敗することに注意してください。
When relying on CORS as a CSRF defense, it is important to realize that certain requests are possible without a preflight. For such requests, called "CORS-safelisted requests", the browser will simply send the request and prevent access to the response if the server did not send the proper CORS headers. This behavior is enforced for requests that can be triggered via other means than JavaScript, such as a GET request or a form-based POST request.
CSRF 防御として CORS に依存する場合、特定のリクエストはプリフライトなしで可能であることを認識することが重要です。「CORS セーフリスト要求」と呼ばれるこのような要求の場合、サーバーが適切な CORS ヘッダーを送信しなかった場合、ブラウザーは単に要求を送信し、応答へのアクセスを阻止します。この動作は、GET リクエストやフォームベースの POST リクエストなど、JavaScript 以外の手段でトリガーできるリクエストに対して適用されます。
The consequence of this behavior is that certain endpoints of the resource server could become vulnerable to CSRF, even with CORS enabled as a defense. For example, if the resource server is an API that exposes an endpoint to a bodiless POST request, there will be no preflight request and no CSRF defense.
この動作の結果、防御として CORS が有効になっている場合でも、リソース サーバーの特定のエンドポイントが CSRF に対して脆弱になる可能性があります。たとえば、リソース サーバーがボディレス POST リクエストにエンドポイントを公開する API である場合、プリフライト リクエストや CSRF 防御は存在しません。
To avoid such bypasses against the CORS policy, the BFF SHOULD require that the browser-based application includes a custom request header. Cross-origin requests with a custom request header always require a preflight, which makes CORS an effective CSRF defense. When this mechanism is used, the BFF MUST ensure that every incoming request carries this static header. The exact naming of this header is at the discretion of the application and BFF. A sample configuration would be a request header with a static value, such as My-Static-Header: 1.
CORS ポリシーに対するこのようなバイパスを回避するために、BFF はブラウザベースのアプリケーションにカスタム要求ヘッダーを含めることを要求する必要があります (SHOULD)。カスタム リクエスト ヘッダーを含むクロスオリジン リクエストには常にプリフライトが必要であり、これにより CORS が効果的な CSRF 防御になります。このメカニズムが使用される場合、BFF はすべての受信リクエストがこの静的ヘッダーを運ぶことを保証しなければなりません (MUST)。このヘッダーの正確な名前は、アプリケーションと BFF の裁量によって決定されます。サンプル構成は、My-Static-Header: 1 などの静的な値を持つリクエスト ヘッダーです。
It is also possible to deploy the browser-based application on the same origin as the BFF. This ensures that legitimate interactions between the frontend and the BFF do not require any preflights, so there's no additional overhead.
ブラウザベースのアプリケーションを BFF と同じオリジンにデプロイすることも可能です。これにより、フロントエンドと BFF の間の正当な対話にはプリフライトが不要になるため、追加のオーバーヘッドが発生しません。
Some technology stacks and frameworks have built-in CSRF protection using anti-forgery cookies. This mechanism relies on a session-specific secret that is stored in a cookie, which can only be read by the legitimate frontend running in the domain associated with the cookie. The frontend is expected to read the cookie and insert its value into the request, typically by adding a custom request header. The backend verifies the value in the cookie to the value provided by the frontend to identify legitimate requests. When implemented correctly for all state-changing requests, this mechanism effectively mitigates CSRF.
一部のテクノロジー スタックとフレームワークには、偽造防止 Cookie を使用した CSRF 保護が組み込まれています。このメカニズムは、Cookie に保存されているセッション固有のシークレットに依存しており、Cookie に関連付けられたドメインで実行されている正規のフロントエンドのみがこのシークレットを読み取ることができます。フロントエンドは、通常はカスタム要求ヘッダーを追加することによって、Cookie を読み取り、その値を要求に挿入することが期待されます。バックエンドは、Cookie 内の値とフロントエンドによって提供された値を検証して、正当なリクエストを識別します。すべての状態変化リクエストに対して正しく実装されると、このメカニズムは効果的に CSRF を軽減します。
Note that this mechanism is not necessarily recommended over the CORS approach. However, if a framework offers built-in support for this mechanism, it can serve as a low-effort alternative to protect against CSRF.
このメカニズムは必ずしも CORS アプローチよりも推奨されるわけではないことに注意してください。ただし、フレームワークがこのメカニズムの組み込みサポートを提供している場合は、CSRF から保護するための低労力の代替手段として機能できます。
The BFF pattern requires that the browser-based application forwards all requests to a resource server through a backend BFF component. As a consequence, the BFF component is able to observe all requests and responses between the application and a resource server, which can have a considerable privacy impact.
BFF パターンでは、ブラウザベースのアプリケーションがバックエンド BFF コンポーネントを通じてすべてのリクエストをリソース サーバーに転送する必要があります。その結果、BFF コンポーネントはアプリケーションとリソース サーバー間のすべてのリクエストと応答を監視できるようになり、プライバシーに多大な影響を与える可能性があります。
When the browser-based application and BFF are built and deployed by the same party, the privacy impact is likely minimal. However, when this pattern is implemented using a BFF component that is provided or hosted by a third party, this privacy impact needs to be taken into account.
ブラウザベースのアプリケーションと BFF が同じ当事者によって構築および展開されている場合、プライバシーへの影響はおそらく最小限です。ただし、サードパーティが提供またはホストする BFF コンポーネントを使用してこのパターンを実装する場合、このプライバシーへの影響を考慮する必要があります。
As the BFF is forwarding all requests to the resource server on behalf of the frontend, care should be taken to ensure the resource server is aware of this component and uses appropriate policies for rate limiting and other anti-abuse measures. For example, if the BFF is deployed as a single-instance service and the resource server is rate limiting requests based on an IP address, the server might start blocking requests as many users' browsers will appear to be coming from the single IP address of the BFF.
BFF はフロントエンドに代わってすべてのリクエストをリソース サーバーに転送するため、リソース サーバーがこのコンポーネントを認識し、レート制限やその他の不正行為対策に適切なポリシーを使用するように注意する必要があります。たとえば、BFF が単一インスタンス サービスとしてデプロイされており、リソース サーバーが IP アドレスに基づいてリクエストをレート制限している場合、多くのユーザーのブラウザが BFF の単一の IP アドレスから送信されているように見えるため、サーバーはリクエストのブロックを開始する可能性があります。
The BFF acts as a proxy service by accepting requests from the frontend and forwarding them to the resource server. The inbound request carries a cookie, which the BFF translates into an access token on the outbound request. (Note that this makes it more like an application-layer reverse proxy rather than an HTTP proxy.) Apart from CSRF attacks, attackers may attempt to manipulate the BFF into forwarding requests to unintended hosts. If an attacker successfully exploits this, they could redirect the BFF to an arbitrary server, potentially exposing the user's access token.
BFF は、フロントエンドからリクエストを受け入れ、リソース サーバーに転送することにより、プロキシ サービスとして機能します。インバウンド要求には Cookie が含まれており、BFF はこれをアウトバウンド要求のアクセス トークンに変換します。(これにより、HTTP プロキシというよりはアプリケーション層のリバース プロキシに似たものになることに注意してください。) CSRF 攻撃とは別に、攻撃者は BFF を操作してリクエストを意図しないホストに転送しようとする可能性があります。攻撃者がこれを悪用すると、BFF を任意のサーバーにリダイレクトし、ユーザーのアクセス トークンが公開される可能性があります。
To mitigate this risk, the BFF MUST enforce strict outbound request controls by validating destination hosts before forwarding requests. This requires maintaining an explicit allowlist of approved resource servers, ensuring that requests are only proxied to predefined backends (e.g., /bff/orders/create maps exclusively to https://order-api.example.com/create). If dynamic routing based on paths (e.g., /bff/orders/{id}) is necessary, the BFF MUST apply strict validation to ensure that only authorized destinations are accessible. Additionally, restricting the allowed HTTP methods on a per-endpoint basis can further reduce attack vectors.
このリスクを軽減するために、BFF はリクエストを転送する前に宛先ホストを検証することにより、厳密なアウトバウンドリクエスト制御を実施しなければなりません (MUST)。これには、承認されたリソース サーバーの明示的な許可リストを維持し、リクエストが事前定義されたバックエンドにのみプロキシされるようにする必要があります (例: /bff/orders/create は https://order-api.example.com/create にのみマップされます)。パス (/bff/orders/{id} など) に基づく動的ルーティングが必要な場合、BFF は厳密な検証を適用して、承認された宛先にのみアクセスできることを確認しなければなりません (MUST)。さらに、許可される HTTP メソッドをエンドポイントごとに制限すると、攻撃ベクトルをさらに減らすことができます。
When implementing a dynamically configurable proxy, the BFF MUST ensure that it only allows requests to explicitly permitted hosts and paths. Failure to enforce these restrictions can lead to unauthorized access and access token leakage.
動的に構成可能なプロキシを実装する場合、BFF は明示的に許可されたホストおよびパスへのリクエストのみを許可することを保証しなければなりません (MUST)。これらの制限を強制しないと、不正アクセスやアクセス トークンの漏洩につながる可能性があります。
In the BFF pattern, all OAuth responsibilities have been moved to the BFF, a server-side component acting as a confidential client. Since server-side applications run in a more controlled environment than browser-based applications, it becomes easier to adopt advanced OAuth security practices. Examples include key-based client authentication and sender-constrained tokens.
BFF パターンでは、すべての OAuth の責任は、機密クライアントとして機能するサーバー側コンポーネントである BFF に移されています。サーバー側アプリケーションはブラウザベースのアプリケーションよりもより制御された環境で実行されるため、高度な OAuth セキュリティ手法を採用することが容易になります。例には、キーベースのクライアント認証や送信者制限付きトークンなどがあります。
This section revisits the attack scenarios and consequences from Section 5 and discusses potential additional defenses.
このセクションでは、セクション 5 の攻撃シナリオとその結果を再検討し、追加の防御策の可能性について説明します。
If the attacker has the ability to execute malicious code (e.g., JavaScript or WASM) in the application's execution context, the following attack scenarios become relevant:
攻撃者がアプリケーションの実行コンテキストで悪意のあるコード (JavaScript や WASM など) を実行できる場合、次の攻撃シナリオが該当します。
* Proxying Requests via the User's Browser (Section 5.1.4)
* ユーザーのブラウザを介したリクエストのプロキシ (セクション 5.1.4)
Note that this attack scenario results in the following consequences:
この攻撃シナリオでは次のような結果が生じることに注意してください。
* Client Hijacking (Section 5.2.3)
* クライアントハイジャック (セクション 5.2.3)
Note that client hijacking is an attack scenario that is inherent to the nature of browser-based applications. As a result, nothing will be able to prevent such attacks apart from stopping the execution of malicious code in the first place. Techniques that can help to achieve this are following secure coding guidelines, code analysis, and deploying defense-in-depth mechanisms such as Content Security Policy [W3C.CSP3].
クライアント ハイジャックは、ブラウザベースのアプリケーションの性質に固有の攻撃シナリオであることに注意してください。その結果、そもそも悪意のあるコードの実行を阻止する以外に、このような攻撃を防ぐことはできなくなります。これを達成するのに役立つ技術は、安全なコーディング ガイドラインに従うこと、コード分析、およびコンテンツ セキュリティ ポリシー [W3C.CSP3] などの多層防御メカニズムの導入です。
In this architecture, the BFF is a key component handling various security-specific responsibilities and proxy-based behavior. While it is out of the scope of this document to discuss a secure implementation of proxy-based applications, it is crucial to note that security vulnerabilities in the BFF can have a significant impact on the application.
このアーキテクチャでは、BFF はさまざまなセキュリティ固有の責任とプロキシ ベースの動作を処理する重要なコンポーネントです。プロキシベースのアプリケーションの安全な実装について説明することはこのドキュメントの範囲外ですが、BFF のセキュリティの脆弱性がアプリケーションに大きな影響を与える可能性があることに注意することが重要です。
Finally, the BFF is uniquely placed to observe all traffic between the browser-based application and the resource servers. If a high-security application would prefer to implement anomaly detection or rate limiting, such a BFF would be the ideal place to do so. Such restrictions can further help to mitigate the consequences of client hijacking.
最後に、BFF はブラウザベースのアプリケーションとリソース サーバー間のすべてのトラフィックを監視するために独自に配置されます。高セキュリティのアプリケーションで異常検出やレート制限の実装を希望する場合、そのような BFF は理想的な場所となります。このような制限は、クライアント ハイジャックの影響を軽減するのにさらに役立ちます。
The other attack scenarios, listed below, are effectively mitigated by the BFF application architecture:
以下にリストする他の攻撃シナリオは、BFF アプリケーション アーキテクチャによって効果的に軽減されます。
* Single-Execution Token Theft (Section 5.1.1)
* 単一実行トークンの盗難 (セクション 5.1.1)
* Persistent Token Theft (Section 5.1.2)
* 永続的なトークンの盗難 (セクション 5.1.2)
* Acquisition and Extraction of New Tokens (Section 5.1.3)
* 新しいトークンの取得と抽出 (セクション 5.1.3)
The BFF counters the first two attack scenarios by not exposing any tokens to the browser-based application. Even when the attacker gains full control over the application, there are simply no tokens to be stolen.
BFF は、ブラウザベースのアプリケーションにトークンを公開しないことで、最初の 2 つの攻撃シナリオに対抗します。攻撃者がアプリケーションを完全に制御できるようになったとしても、盗まれるトークンはまったくありません。
The third scenario, where the attacker obtains a fresh access token (and optionally refresh token) by running a silent flow, is mitigated by making the BFF a confidential client. Even when the attacker manages to obtain an authorization code, they are prevented from exchanging this code due to the lack of client credentials. Additionally, the use of PKCE prevents other attacks against the authorization code.
3 番目のシナリオは、攻撃者がサイレント フローを実行して新しいアクセス トークン (および必要に応じてリフレッシュ トークン) を取得するシナリオですが、BFF を機密クライアントにすることで軽減されます。攻撃者が認証コードを取得できたとしても、クライアントの資格情報がないため、このコードを交換することはできません。さらに、PKCE を使用すると、認証コードに対する他の攻撃を防ぐことができます。
Since refresh and access tokens are managed by the BFF and not exposed to the browser, the following two consequences of potential attacks become irrelevant:
リフレッシュ トークンとアクセス トークンは BFF によって管理され、ブラウザーには公開されないため、潜在的な攻撃による次の 2 つの影響は無関係になります。
* Exploiting Stolen Refresh Tokens (Section 5.2.1)
* 盗まれたリフレッシュ トークンの悪用 (セクション 5.2.1)
* Exploiting Stolen Access Tokens (Section 5.2.2)
* 盗まれたアクセストークンの悪用 (セクション 5.2.2)
The architecture of a BFF is significantly more complicated than a browser-only application. It requires deploying and operating a server-side BFF component. Additionally, this pattern requires all interactions between the application and the resource servers to be proxied by the BFF. Depending on the deployment pattern, this proxy behavior can add a significant burden on the server-side components. See Section 6.2.2.6 for additional notes if the BFF is acting as the resource server.
BFF のアーキテクチャは、ブラウザのみのアプリケーションよりも大幅に複雑です。サーバー側の BFF コンポーネントを展開して操作する必要があります。さらに、このパターンでは、アプリケーションとリソース サーバー間のすべての対話が BFF によってプロキシされる必要があります。デプロイメント パターンによっては、このプロキシ動作によりサーバー側コンポーネントに大きな負担がかかる可能性があります。BFF がリソース サーバーとして機能する場合の追加の注意事項については、セクション 6.2.2.6 を参照してください。
However, because of the nature of the BFF architecture pattern, it offers strong security guarantees. Using a BFF also ensures that the application's attack surface does not increase by using OAuth. The only viable attack pattern is hijacking the client application in the user's browser -- a problem inherent to web applications.
ただし、BFF アーキテクチャ パターンの性質により、強力なセキュリティが保証されます。BFF を使用すると、OAuth の使用によってアプリケーションの攻撃対象領域が増加することもなくなります。唯一の実行可能な攻撃パターンは、ユーザーのブラウザーでクライアント アプリケーションをハイジャックすることです。これは Web アプリケーションに固有の問題です。
This architecture is strongly recommended for business applications, sensitive applications, and applications that handle personal data.
このアーキテクチャは、ビジネス アプリケーション、機密性の高いアプリケーション、個人データを扱うアプリケーションに強く推奨されます。
This section describes the architecture of a browser-based application that relies on a backend component to handle OAuth responsibilities for obtaining tokens as a confidential client (as defined in Section 2.1 of [RFC6749]). The backend component then provides the application with the access token to directly interact with resource servers.
このセクションでは、([RFC6749] のセクション 2.1 で定義されている) 機密クライアントとしてトークンを取得するための OAuth 責任を処理するバックエンド コンポーネントに依存するブラウザベースのアプリケーションのアーキテクチャについて説明します。次に、バックエンド コンポーネントは、リソース サーバーと直接対話するためのアクセス トークンをアプリケーションに提供します。
The token-mediating backend pattern is more lightweight than the BFF pattern (see Section 6.1), since it does not require the proxying of all requests and responses between the application and the resource server. From a security perspective, the token-mediating backend is less secure than a BFF but still offers significant advantages over an OAuth client application running directly in the browser.
トークン仲介バックエンド パターンは、アプリケーションとリソース サーバーの間ですべてのリクエストと応答をプロキシする必要がないため、BFF パターン (セクション 6.1 を参照) よりも軽量です。セキュリティの観点から見ると、トークン仲介バックエンドは BFF よりも安全性が劣りますが、それでもブラウザーで直接実行される OAuth クライアント アプリケーションよりも大きな利点があります。
If an attacker is able to execute malicious code within the application, the application architecture is able to prevent the attacker from abusing refresh tokens (see "Single-Execution Token Theft" (Section 5.1.1) and "Persistent Token Theft" (Section 5.1.2)) or obtaining a fresh set of tokens (see "Acquisition and Extraction of New Tokens" (Section 5.1.3)). However, since the access token is directly exposed to the application, the attacker can steal the token from client-side storage (see "Single-Execution Token Theft" (Section 5.1.1) and "Persistent Token Theft" (Section 5.1.2)) or request a fresh token from the token-mediating backend (see "Proxying Requests via the User's Browser" (Section 5.1.4)). Note that the use of HttpOnly cookies prevents the attacker from directly accessing the session state, which prevents the escalation from access token theft to session hijacking.
攻撃者がアプリケーション内で悪意のあるコードを実行できる場合、アプリケーション アーキテクチャは、攻撃者によるリフレッシュ トークンの悪用 (「単一実行トークンの盗難」 (セクション 5.1.1) および「永続的トークンの盗難」 (セクション 5.1.2) を参照) や新しいトークンのセットの取得 (「新しいトークンの取得と抽出」 (セクション 5.1.3) を参照) を防ぐことができます。ただし、アクセス トークンはアプリケーションに直接公開されるため、攻撃者はクライアント側のストレージからトークンを盗んだり (「単一実行トークンの盗難」 (セクション 5.1.1) および「永続的なトークンの盗難」 (セクション 5.1.2) を参照)、トークンを仲介するバックエンドから新しいトークンを要求したり (「ユーザーのブラウザを介したリクエストのプロキシ」 (セクション 5.1.4) を参照) する可能性があります。HttpOnly Cookie を使用すると、攻撃者がセッション状態に直接アクセスできなくなり、アクセス トークンの盗難からセッション ハイジャックへのエスカレーションが防止されることに注意してください。
+---------------+ +----------+ +----------+
| | | | | |
| Authorization | | Token | | Resource |
| Endpoint | | Endpoint | | Server |
| | | | | |
+---------------+ +----------+ +----------+
^ ^ ^
| (F)| |
| v |
| |
| +---------------------------+ |
| | | |
| | Token-Mediating Backend | |(J)
(D)| | | |
| +---------------------------+ |
| |
| ^ ^ ^ + |
| (B,I)| (C)| (E)| (G)| |
v v v + v v
+-----------------+ +-----------------------------------------+
| | (A,H) | |
| Static Web Host | +-----> | Browser |
| | | |
+-----------------+ +-----------------------------------------+
Figure 2: OAuth 2.0 Token-Mediating Backend Pattern
図 2: OAuth 2.0 トークン仲介バックエンド パターン
In this architecture, the browser-based code (e.g., JavaScript or WASM) is first loaded from a static web host into the browser (A), and the application then runs in the browser. The application checks with the token-mediating backend if there is an active session (B). If an active session is found, the application receives the corresponding access token, resumes its authenticated state, and skips forward to (J).
このアーキテクチャでは、ブラウザベースのコード (JavaScript や WASM など) が最初に静的 Web ホストからブラウザにロードされ (A)、次にアプリケーションがブラウザ内で実行されます。アプリケーションは、アクティブなセッションがあるかどうかをトークン仲介バックエンドで確認します (B)。アクティブなセッションが見つかった場合、アプリケーションは対応するアクセス トークンを受け取り、認証状態を再開し、(J) に進みます。
When no active session is found, the application triggers a navigation to the token-mediating backend (C) to initiate the Authorization Code flow with the PKCE extension (described in Section 6.2.3.1), to which the token-mediating backend responds by redirecting the browser to the authorization endpoint (D). When the user is redirected back, the browser delivers the authorization code to the token-mediating backend (E), where the token-mediating backend can then exchange it for tokens at the token endpoint (F) using its client credentials and PKCE code verifier.
アクティブなセッションが見つからない場合、アプリケーションはトークン仲介バックエンド (C) へのナビゲーションをトリガーして、PKCE 拡張機能 (セクション 6.2.3.1 で説明) を使用して認可コード フローを開始します。トークン仲介バックエンドは、ブラウザを認可エンドポイント (D) にリダイレクトすることで応答します。ユーザーがリダイレクトされると、ブラウザーは認証コードをトークン仲介バックエンド (E) に配信します。トークン仲介バックエンドは、クライアント資格情報と PKCE コード検証機能を使用して、トークン エンドポイント (F) でそのコードをトークンと交換できます。
The token-mediating backend associates the obtained tokens with the user's session (see Section 6.2.2.4) and sets a cookie in the response to keep track of this session (G). This response to the browser will also trigger the reloading of the application (H). When this application reloads, it will check with the token-mediating backend for an existing session (I), allowing the application to resume its authenticated state and obtain the access token from the token-mediating backend.
トークン仲介バックエンドは、取得したトークンをユーザーのセッションに関連付け (セクション 6.2.2.4 を参照)、応答に Cookie を設定してこのセッションを追跡します (G)。ブラウザへのこの応答は、アプリケーションのリロードもトリガーします (H)。このアプリケーションはリロードすると、トークン仲介バックエンドで既存のセッション (I) を確認し、アプリケーションが認証状態を再開して、トークン仲介バックエンドからアクセス トークンを取得できるようにします。
The application in the browser can use the access token obtained in (I) to directly make requests to the resource server (J).
ブラウザ上のアプリケーションは、(I)で取得したアクセストークンを使用して、リソースサーバーに直接リクエストを行うことができます(J)。
Most of the endpoint implementations of the token-mediating backend are similar to those described for a BFF.
トークン仲介バックエンドのエンドポイント実装のほとんどは、BFF について説明したものと似ています。
* The "check session" endpoint ((B) and (I) in Figure 2) is an API endpoint called by the browser-based application. The request will carry session information when available, allowing the backend to check for an active session. The response should indicate to the browser-based application whether the session is active. If an active session is found, the backend includes the access token in the response. Additionally, the backend can include other information, such as identity information about the authenticated user.
* 「チェックセッション」エンドポイント (図 2 の (B) および (I)) は、ブラウザベースのアプリケーションによって呼び出される API エンドポイントです。セッション情報が利用可能な場合、リクエストにはセッション情報が含まれるため、バックエンドはアクティブなセッションを確認できます。応答は、セッションがアクティブであるかどうかをブラウザベースのアプリケーションに示す必要があります。アクティブなセッションが見つかった場合、バックエンドは応答にアクセス トークンを含めます。さらに、バックエンドには、認証されたユーザーに関する ID 情報などの他の情報を含めることができます。
* The endpoint that initiates the Authorization Code flow (C) is identical to the endpoint described for the BFF architecture. See Section 6.1.2.1 for more details.
* 認可コード フロー (C) を開始するエンドポイントは、BFF アーキテクチャについて説明したエンドポイントと同じです。詳細については、セクション 6.1.2.1 を参照してください。
* The endpoint that receives the authorization code (E) is identical to the endpoint described for the BFF architecture. See Section 6.1.2.1 for more details.
* 認証コード (E) を受信するエンドポイントは、BFF アーキテクチャについて説明したエンドポイントと同じです。詳細については、セクション 6.1.2.1 を参照してください。
* The endpoint that supports logout is identical to the endpoint described for the BFF architecture. See Section 6.1.2.1 for more details.
* ログアウトをサポートするエンドポイントは、BFF アーキテクチャについて説明したエンドポイントと同じです。詳細については、セクション 6.1.2.1 を参照してください。
When using refresh tokens, as described in Section 4.14 of [RFC9700], the token-mediating backend obtains the refresh token in (F) and associates it with the user's session.
[RFC9700] のセクション 4.14 で説明されているように、リフレッシュ トークンを使用する場合、トークン仲介バックエンドは (F) でリフレッシュ トークンを取得し、それをユーザーのセッションに関連付けます。
If the resource server rejects the access token, the application can contact the token-mediating backend to request a new access token. The token-mediating backend relies on the cookies associated with this request to look up the user's refresh token and makes a token request using the refresh token. These steps are not shown in Figure 2. Note that this refresh token request is from the backend, a confidential client, and thus requires client authentication.
リソース サーバーがアクセス トークンを拒否した場合、アプリケーションはトークン仲介バックエンドに接続して新しいアクセス トークンを要求できます。トークン仲介バックエンドは、このリクエストに関連付けられた Cookie に依存してユーザーのリフレッシュ トークンを検索し、リフレッシュ トークンを使用してトークン リクエストを作成します。これらの手順は図 2 には示されていません。このリフレッシュ トークン リクエストはバックエンド、つまり機密クライアントからのものであるため、クライアント認証が必要であることに注意してください。
When the refresh token expires, there is no way to obtain a valid access token without starting an entirely new Authorization Code grant. Therefore, it makes sense to configure the lifetime of the cookie-based session to be equal to the maximum lifetime of the refresh token if such information is known upfront. Additionally, when the token-mediating backend learns that a refresh token for an active session is no longer valid, it makes sense to invalidate the session.
リフレッシュ トークンの有効期限が切れると、まったく新しい認証コード付与を開始する以外に有効なアクセス トークンを取得する方法はありません。したがって、そのような情報が事前にわかっている場合は、Cookie ベースのセッションの有効期間をリフレッシュ トークンの最大有効期間と等しくなるように構成することが合理的です。さらに、アクティブなセッションのリフレッシュ トークンが有効でなくなったことをトークン仲介バックエンドが認識した場合、セッションを無効にすることは理にかなっています。
Depending on the resource servers being accessed and the configuration of scopes at the authorization server, the application may wish to request access tokens with different scope configurations. This behavior would allow the application to follow the best practice of using minimally scoped access tokens.
アクセスされるリソース サーバーと認可サーバーのスコープの構成に応じて、アプリケーションは異なるスコープ構成のアクセス トークンを要求する場合があります。この動作により、アプリケーションは最小限のスコープのアクセス トークンを使用するベスト プラクティスに従うことができます。
The application can inform the token-mediating backend of the desired scopes when it checks for the active session ((A) and (I)). It is up to the token-mediating backend to decide if previously obtained access tokens fall within the desired scope criteria.
アプリケーションは、アクティブなセッション ((A) および (I)) をチェックするときに、トークン仲介バックエンドに必要なスコープを通知できます。以前に取得したアクセス トークンが目的のスコープ基準内に収まるかどうかを判断するのは、トークンを仲介するバックエンド次第です。
It should be noted that this access token caching mechanism at the token-mediating backend can cause scope-elevation risks when applied indiscriminately. If the cached access token features a superset of the scopes requested by the frontend, the token-mediating backend SHOULD NOT return it to the frontend; instead, it SHOULD use the refresh token to request an access token with the smaller set of scopes from the authorization server. Note that support of such an access token downscoping mechanism is at the discretion of the authorization server.
トークン仲介バックエンドでのこのアクセス トークン キャッシュ メカニズムは、無差別に適用するとスコープ昇格のリスクを引き起こす可能性があることに注意してください。キャッシュされたアクセス トークンが、フロントエンドによって要求されたスコープのスーパーセットを特徴とする場合、トークン仲介バックエンドはそれをフロントエンドに返してはなりません (SHOULD NOT)。代わりに、リフレッシュ トークンを使用して、より小さいスコープのセットを持つアクセス トークンを認可サーバーから要求する必要があります (SHOULD)。このようなアクセス トークンのダウンスコープ メカニズムのサポートは、認可サーバーの裁量に任されていることに注意してください。
The token-mediating backend can use a similar mechanism to the downscoping mechanism when relying on the extension described in [RFC8707] to obtain an access token for a specific resource server.
トークン仲介バックエンドは、[RFC8707] で説明されている拡張機能に依存して特定のリソース サーバーのアクセス トークンを取得する場合、ダウンスコープ メカニズムと同様のメカニズムを使用できます。
Similar to the BFF, the token-mediating backend relies on browser cookies to keep track of the user's session. The implementation guidelines and security considerations for cookie-based sessions are the same as those for a BFF, as discussed in Section 6.1.2.3.
BFF と同様に、トークン仲介バックエンドはブラウザーの Cookie に依存してユーザーのセッションを追跡します。Cookie ベースのセッションの実装ガイドラインとセキュリティに関する考慮事項は、セクション 6.1.2.3 で説明した BFF の場合と同じです。
Similar to a BFF, the token-mediating backend can choose to combine OAuth and OpenID Connect in a single flow. See Section 6.1.2.4 for more details.
BFF と同様に、トークン仲介バックエンドは OAuth と OpenID Connect を 1 つのフローに組み合わせることができます。詳細については、セクション 6.1.2.4 を参照してください。
Hosting the static JavaScript or WASM code is a separate responsibility from handling interactions with the authorization server. In Figure 2, the token-mediating backend and static web host are shown as two separate entities. In real-world deployment scenarios, these components can be deployed as a single service (i.e., the token-mediating backend serving the static code), as two separate services (i.e., a CDN and a token-mediating backend), or as two components in a single service (i.e., static hosting and serverless functions on a cloud platform). These deployment differences do not affect the relationships described in this pattern but may impact other practicalities, such as the need to properly configure CORS to enable cross-origin communication.
静的 JavaScript または WASM コードのホストは、認可サーバーとの対話の処理とは別の責任です。図 2 では、トークン仲介バックエンドと静的 Web ホストが 2 つの別個のエンティティとして示されています。実際の展開シナリオでは、これらのコンポーネントは、単一のサービス (つまり、静的コードを提供するトークン仲介バックエンド) として、2 つの別個のサービス (つまり、CDN とトークン仲介バックエンド) として、または 1 つのサービス内の 2 つのコンポーネント (つまり、クラウド プラットフォーム上の静的ホスティングとサーバーレス機能) として展開できます。これらの展開の違いは、このパターンで説明されている関係には影響しませんが、クロスオリジン通信を可能にするために CORS を適切に構成する必要性など、他の実用性に影響を与える可能性があります。
The main benefit of using a token-mediating backend is the backend's ability to act as a confidential client. Therefore, the token-mediating backend MUST act as a confidential client. Furthermore, the token-mediating backend MUST use the OAuth 2.0 Authorization Code grant as described in Section 2.1.1 of [RFC9700] to initiate a request for an access token.
トークン仲介バックエンドを使用する主な利点は、バックエンドが機密クライアントとして機能できることです。したがって、トークン仲介バックエンドは機密クライアントとして機能しなければなりません。さらに、トークン仲介バックエンドは、[RFC9700] のセクション 2.1.1 で説明されているように、OAuth 2.0 認可コード許可を使用して、アクセス トークンのリクエストを開始しなければなりません (MUST)。
The token-mediating backend uses cookies to create a user session, which is directly associated with the user's tokens through either server-side or client-side session state. The same cookie security guidelines established for a BFF also apply, as discussed in Section 6.1.3.2.
トークン仲介バックエンドは、Cookie を使用してユーザー セッションを作成します。このセッションは、サーバー側またはクライアント側のセッション状態を通じてユーザーのトークンに直接関連付けられます。セクション 6.1.3.2 で説明したように、BFF に対して確立された同じ Cookie セキュリティ ガイドラインも適用されます。
Interactions between the browser-based application and the token-mediating backend rely on cookies for authentication and authorization. Just like a BFF, the token-mediating backend is required to account for CSRF attacks.
ブラウザベースのアプリケーションとトークンを仲介するバックエンド間の対話は、認証と承認のために Cookie に依存します。BFF と同様に、トークン仲介バックエンドは CSRF 攻撃に対応する必要があります。
Section 6.1.3.3 outlines the nuances of various mitigation strategies against CSRF attacks. Specifically for a token-mediating backend, these CSRF defenses only apply to the endpoint or endpoints where the application can obtain its access tokens.
セクション 6.1.3.3 では、CSRF 攻撃に対するさまざまな緩和戦略の微妙な違いについて概説します。特にトークン仲介バックエンドの場合、これらの CSRF 防御は、アプリケーションがアクセス トークンを取得できるエンドポイントにのみ適用されます。
The token-mediating backend is a confidential client running as a server-side component. The token-mediating backend can adopt security best practices for confidential clients, such as key-based client authentication.
トークン仲介バックエンドは、サーバー側コンポーネントとして実行される機密クライアントです。トークン仲介バックエンドは、キーベースのクライアント認証など、機密クライアントに対するセキュリティのベスト プラクティスを採用できます。
This section revisits the attack scenarios and consequences from Section 5 and discusses potential additional defenses.
このセクションでは、セクション 5 の攻撃シナリオとその結果を再検討し、追加の防御策の可能性について説明します。
If the attacker has the ability to execute malicious code in the application's execution context, the following attack scenarios become relevant:
攻撃者がアプリケーションの実行コンテキストで悪意のあるコードを実行できる場合、次の攻撃シナリオが関連します。
* Single-Execution Token Theft (Section 5.1.1) for access tokens
* アクセス トークンの単一実行トークンの盗難 (セクション 5.1.1)
* Persistent Token Theft (Section 5.1.2) for access tokens
* アクセストークンの永続的トークンの盗難 (セクション 5.1.2)
* Proxying Requests via the User's Browser (Section 5.1.4)
* ユーザーのブラウザを介したリクエストのプロキシ (セクション 5.1.4)
Note that these attack scenarios result in the following consequences:
これらの攻撃シナリオは次の結果をもたらすことに注意してください。
* Exploiting Stolen Access Tokens (Section 5.2.2)
* 盗まれたアクセストークンの悪用 (セクション 5.2.2)
* Client Hijacking (Section 5.2.3)
* クライアントハイジャック (セクション 5.2.3)
Exposing the access token to the browser-based application is the core idea behind the architecture pattern of the token-mediating backend. As a result, the access token becomes vulnerable to token theft by malicious browser-based code.
アクセス トークンをブラウザベースのアプリケーションに公開することは、トークン仲介バックエンドのアーキテクチャ パターンの背後にある中心的なアイデアです。その結果、アクセス トークンは、悪意のあるブラウザベースのコードによるトークンの盗難に対して脆弱になります。
The other attack scenarios (listed below) are effectively mitigated by the token-mediating backend:
他の攻撃シナリオ (以下にリスト) は、トークン仲介バックエンドによって効果的に軽減されます。
* Single-Execution Token Theft (Section 5.1.1) for refresh tokens
* リフレッシュ トークンの単一実行トークンの盗難 (セクション 5.1.1)
* Persistent Token Theft (Section 5.1.2) for refresh tokens
* リフレッシュ トークンの永続的トークンの盗難 (セクション 5.1.2)
* Acquisition and Extraction of New Tokens (Section 5.1.3)
* 新しいトークンの取得と抽出 (セクション 5.1.3)
The token-mediating backend counters the first two attack scenarios by not exposing the refresh token to the browser-based application. Even when the attacker gains full control over the application, there are simply no refresh tokens to be stolen.
トークン仲介バックエンドは、ブラウザベースのアプリケーションにリフレッシュ トークンを公開しないことで、最初の 2 つの攻撃シナリオに対抗します。攻撃者がアプリケーションを完全に制御できるようになった場合でも、更新トークンが盗まれることはありません。
The third scenario, where the attacker obtains a fresh access token (and optionally refresh token) by running a silent flow, is mitigated by making the token-mediating backend a confidential client. Even when the attacker manages to obtain an authorization code, they are prevented from exchanging this code due to the lack of client credentials. Additionally, the use of PKCE prevents other attacks against the authorization code.
3 番目のシナリオは、攻撃者がサイレント フローを実行して新しいアクセス トークン (および必要に応じてリフレッシュ トークン) を取得するシナリオですが、トークンを仲介するバックエンドを機密クライアントにすることで軽減されます。攻撃者が認証コードを取得できたとしても、クライアントの資格情報がないため、このコードを交換することはできません。さらに、PKCE を使用すると、認証コードに対する他の攻撃を防ぐことができます。
Because of the nature of the token-mediating backend, the following consequences of potential attacks become irrelevant:
トークン仲介バックエンドの性質により、潜在的な攻撃による次の影響は無関係になります。
* Exploiting Stolen Refresh Tokens (Section 5.2.1)
* 盗まれたリフレッシュ トークンの悪用 (セクション 5.2.1)
While this architecture inherently exposes access tokens, there are some additional defenses that can help to increase the security posture of the application.
このアーキテクチャは本質的にアクセス トークンを公開しますが、アプリケーションのセキュリティ体制を強化するのに役立つ追加の防御手段がいくつかあります。
Given the nature of the token-mediating backend pattern, there is no need for persistent token storage in the browser. When needed, the application can always use its cookie-based session to obtain an access token from the token-mediating backend. Section 8 provides more details on the security properties of various storage mechanisms in the browser.
トークン仲介バックエンド パターンの性質を考慮すると、ブラウザーに永続的なトークンを保存する必要はありません。必要に応じて、アプリケーションはいつでも Cookie ベースのセッションを使用して、トークン仲介バックエンドからアクセス トークンを取得できます。セクション 8 では、ブラウザのさまざまなストレージ メカニズムのセキュリティ プロパティについて詳しく説明します。
Be aware that even when the access token is stored out of reach of malicious browser-based code, the malicious code can still mimic the legitimate application and send a request to the token-mediation backend to obtain the latest access token.
アクセス トークンが悪意のあるブラウザベースのコードの届かない場所に保存されている場合でも、悪意のあるコードは正規のアプリケーションを模倣し、トークン仲介バックエンドにリクエストを送信して最新のアクセス トークンを取得する可能性があることに注意してください。
Using sender-constrained access tokens is not trivial in this architecture. The token-mediating backend is responsible for exchanging an authorization code or refresh token for an access token, but the application will use the access token. Using a mechanism such as DPoP [RFC9449] would require splitting responsibilities over two parties, which is not a scenario defined by the specification. Use of DPoP in such a scenario is out of the scope of this document.
このアーキテクチャでは、送信者制約のアクセス トークンを使用することは簡単ではありません。トークン仲介バックエンドは、認証コードまたはリフレッシュ トークンをアクセス トークンと交換する責任がありますが、アプリケーションはアクセス トークンを使用します。DPoP [RFC9449] などのメカニズムを使用するには、2 者間で責任を分割する必要がありますが、これは仕様で定義されたシナリオではありません。このようなシナリオでの DPoP の使用は、このドキュメントの範囲外です。
The architecture of a token-mediating backend is more complicated than a browser-only application but is less complicated than running a proxying BFF. Similarly, the security properties offered by the token-mediating backend lie somewhere between using a BFF and running a browser-only application.
トークン仲介バックエンドのアーキテクチャは、ブラウザー専用アプリケーションよりも複雑ですが、プロキシ BFF の実行ほど複雑ではありません。同様に、トークン仲介バックエンドによって提供されるセキュリティ プロパティは、BFF の使用とブラウザー専用アプリケーションの実行の間のどこかにあります。
A token-mediating backend addresses typical scenarios that grant the attacker long-term access on behalf of the user. However, due to the consequence of access token theft, the attacker still has the ability to gain direct access to resource servers.
トークン仲介バックエンドは、ユーザーに代わって攻撃者に長期アクセスを許可する一般的なシナリオに対処します。ただし、アクセス トークンの盗難の結果、攻撃者は依然としてリソース サーバーに直接アクセスする能力を持っています。
When considering a token-mediating backend architecture, it is strongly recommended to evaluate if adopting a full BFF as discussed in Section 6.1 is a viable alternative. Only when the use cases or system requirements would prevent the use of a proxying BFF should the token-mediating backend be considered over a full BFF.
トークン仲介バックエンド アーキテクチャを検討する場合、セクション 6.1 で説明した完全な BFF の採用が実行可能な代替案であるかどうかを評価することを強くお勧めします。ユースケースまたはシステム要件によりプロキシ BFF の使用が妨げられる場合にのみ、トークン仲介バックエンドを完全な BFF よりも考慮する必要があります。
This section describes the architecture of a browser-based application that acts as the OAuth client, handling all OAuth responsibilities in the browser. As a result, the browser-based application obtains tokens from the authorization server, without the involvement of a backend component.
このセクションでは、OAuth クライアントとして機能し、ブラウザ内ですべての OAuth の役割を処理するブラウザベースのアプリケーションのアーキテクチャについて説明します。その結果、ブラウザベースのアプリケーションは、バックエンド コンポーネントを介さずに、認可サーバーからトークンを取得します。
If an attacker is able to execute malicious code in the browser, this application architecture is vulnerable to all attack scenarios discussed earlier (Section 5.1). In essence, the attacker will be able to obtain access tokens and refresh tokens from the authorization server, potentially giving them long-term access to protected resources on behalf of the user.
攻撃者がブラウザで悪意のあるコードを実行できる場合、このアプリケーション アーキテクチャは、前述したすべての攻撃シナリオに対して脆弱になります (セクション 5.1)。基本的に、攻撃者は認可サーバーからアクセス トークンとリフレッシュ トークンを取得できるため、ユーザーに代わって保護されたリソースへの長期アクセスが可能になる可能性があります。
+---------------+ +--------------+
| | | |
| Authorization | | Resource |
| Server | | Server |
| | | |
+---------------+ +--------------+
^ ^ ^ +
| | | |
|(B) |(C) |(D) |(E)
| | | |
| | | |
+ v + v
+-----------------+ +-------------------------------+
| | (A) | |
| Static Web Host | +-----> | Browser |
| | | |
+-----------------+ +-------------------------------+
Figure 3: Browser-Based OAuth 2.0 Client Pattern
図 3: ブラウザベースの OAuth 2.0 クライアント パターン
In this architecture, the code is first loaded from a static web host into the browser (A), and then the application runs in the browser. In this scenario, the browser-based application is considered a public client, which does not possess client credentials to authenticate to the authorization server.
このアーキテクチャでは、最初にコードが静的 Web ホストからブラウザにロードされ (A)、次にアプリケーションがブラウザで実行されます。このシナリオでは、ブラウザベースのアプリケーションはパブリック クライアントとみなされ、認可サーバーに対して認証するためのクライアント資格情報を所有しません。
The application obtains an authorization code (B) by initiating the Authorization Code flow with the PKCE extension (described in Section 6.3.2.1). The application uses a browser API (e.g., [Fetch]) to make a POST request to the token endpoint (C) to exchange the authorization code for tokens.
アプリケーションは、PKCE 拡張機能 (セクション 6.3.2.1 で説明) を使用して認証コード フローを開始することにより、認証コード (B) を取得します。アプリケーションはブラウザ API ([Fetch] など) を使用してトークン エンドポイント (C) に POST リクエストを送信し、トークンの認可コードを交換します。
The application is then responsible for storing the access token and optional refresh token as securely as possible using appropriate browser APIs, as described in Section 8.
アプリケーションは、セクション 8 で説明されているように、適切なブラウザ API を使用して、アクセス トークンとオプションのリフレッシュ トークンをできるだけ安全に保存する責任があります。
When the application in the browser wants to make a request to the resource server, it can interact with the resource server directly. The application includes the access token in the request (D) and receives the resource server's response (E).
ブラウザ内のアプリケーションがリソース サーバーにリクエストを行う場合、リソース サーバーと直接対話できます。アプリケーションはリクエストにアクセス トークンを含め (D)、リソース サーバーの応答を受信します (E)。
Browser-based applications that are public clients (Section 2.1 of [RFC6749]) and use the Authorization Code grant type described in Section 4.1 of [RFC6749] MUST also follow the additional requirements described in this section.
パブリッククライアント ([RFC6749] のセクション 2.1) であり、[RFC6749] のセクション 4.1 で説明されている認可コード付与タイプを使用するブラウザベースのアプリケーションは、このセクションで説明されている追加要件にも従わなければなりません (MUST)。
Browser-based applications that are public clients MUST implement the PKCE [RFC7636] extension when obtaining an access token, and authorization servers MUST support and enforce PKCE for such clients.
パブリック クライアントであるブラウザベースのアプリケーションは、アクセス トークンを取得するときに PKCE [RFC7636] 拡張機能を実装しなければならず (MUST)、認可サーバーはそのようなクライアントに対して PKCE をサポートし強制しなければなりません (MUST)。
The PKCE extension prevents an attack where the authorization code is intercepted and exchanged for an access token by a malicious client by providing the authorization server with a way to verify that the client instance that exchanges the authorization code is the same one that initiated the flow.
PKCE 拡張機能は、認可コードを交換するクライアント インスタンスがフローを開始したものと同じであることを検証する方法を認可サーバーに提供することで、悪意のあるクライアントによって認可コードが傍受され、アクセス トークンと交換される攻撃を防ぎます。
Browser-based applications MUST prevent CSRF attacks against their redirect URI. This can be accomplished by any of the below:
ブラウザベースのアプリケーションは、リダイレクト URI に対する CSRF 攻撃を防止しなければなりません (MUST)。これは、以下のいずれかによって実現できます。
* configuring the authorization server to require PKCE for this client
* このクライアントに PKCE を要求するように認可サーバーを構成する
* using and verifying unique value for the OAuth state parameter to carry a CSRF token
* CSRF トークンを運ぶための OAuth 状態パラメータの一意の値の使用と検証
* using and verifying the OpenID Connect nonce parameter as described in [OpenID] if the application is also using OpenID Connect
* アプリケーションが OpenID Connect も使用している場合は、[OpenID] で説明されているように OpenID Connect nonce パラメーターを使用して検証する
See Section 2.1 of [RFC9700] for additional details on selecting a proper CSRF defense for the Authorization Code flow.
認可コードフローに対する適切な CSRF 防御の選択の詳細については、[RFC9700] のセクション 2.1 を参照してください。
For browser-based clients, the refresh token is typically a bearer token unless the application explicitly uses DPoP [RFC9449]. As a result, the risk of leaked refresh tokens is greater than that of leaked access tokens, since an attacker may be able to continue using the stolen refresh token to obtain new access tokens potentially without being detected by the authorization server.
ブラウザベースのクライアントの場合、アプリケーションが明示的に DPoP [RFC9449] を使用しない限り、リフレッシュ トークンは通常ベアラー トークンです。その結果、攻撃者が認可サーバーに検出されることなく、盗まれたリフレッシュ トークンを使用し続けて新しいアクセス トークンを取得できる可能性があるため、リフレッシュ トークンが漏洩するリスクはアクセス トークンが漏洩するリスクよりも高くなります。
Authorization servers may choose whether or not to issue refresh tokens to browser-based applications. However, in light of the impact of third-party cookie-blocking mechanisms, the use of refresh tokens has become significantly more attractive. [RFC9700] describes some additional requirements around refresh tokens on top of the recommendations of [RFC6749]. Applications and authorization servers conforming to this BCP MUST also follow the recommendations in [RFC9700] for refresh tokens if refresh tokens are issued to browser-based applications.
認可サーバーは、ブラウザベースのアプリケーションにリフレッシュ トークンを発行するかどうかを選択できます。ただし、サードパーティの Cookie ブロック メカニズムの影響を考慮すると、リフレッシュ トークンの使用が非常に魅力的になっています。[RFC9700] では、[RFC6749] の推奨事項に加えて、リフレッシュ トークンに関するいくつかの追加要件について説明しています。この BCP に準拠するアプリケーションと認可サーバーは、ブラウザベースのアプリケーションにリフレッシュ トークンが発行される場合、リフレッシュ トークンに関する [RFC9700] の推奨事項にも従わなければなりません (MUST)。
In particular, authorization servers:
特に、認可サーバーは次のことを行います。
* MUST either rotate refresh tokens on each use OR use sender-constrained refresh tokens as described in Section 4.14.2 of [RFC9700]
* [RFC9700] のセクション 4.14.2 に記載されているように、使用するたびにリフレッシュ トークンをローテーションするか、送信者制約のリフレッシュ トークンを使用しなければなりません (MUST)。
* MUST either set a maximum lifetime on refresh tokens OR expire if the refresh token has not been used within some amount of time
* リフレッシュ トークンの最大有効期間を設定するか、リフレッシュ トークンが一定の時間内に使用されなかった場合に期限切れになるかのいずれかを行う必要があります。
* MUST NOT, upon issuing a rotated refresh token, extend the lifetime of the new refresh token beyond the lifetime of the initial refresh token if the refresh token has a preestablished expiration time
* リフレッシュ トークンに有効期限が事前に設定されている場合、ローテーションされたリフレッシュ トークンの発行時に、最初のリフレッシュ トークンの有効期間を超えて新しいリフレッシュ トークンの有効期間を延長してはなりません。
Limiting the overall refresh token lifetime to the lifetime of the initial refresh token ensures a stolen refresh token cannot be used indefinitely.
全体的なリフレッシュ トークンの有効期間を最初のリフレッシュ トークンの有効期間に制限することで、盗まれたリフレッシュ トークンを無期限に使用できなくなります。
For example:
例えば:
* A user authorizes an application, issuing an access token that lasts 10 minutes and a refresh token that lasts 8 hours.
* ユーザーはアプリケーションを承認し、10 分間持続するアクセス トークンと 8 時間持続するリフレッシュ トークンを発行します。
* After 10 minutes, the initial access token expires, so the application uses the refresh token to get a new access token.
* 10 分後に最初のアクセス トークンの有効期限が切れるため、アプリケーションは更新トークンを使用して新しいアクセス トークンを取得します。
* The authorization server returns a new access token that lasts 10 minutes and a new refresh token that lasts 7 hours and 50 minutes.
* 認可サーバーは、10 分間持続する新しいアクセス トークンと、7 時間 50 分持続する新しい更新トークンを返します。
* This continues until 8 hours pass from the initial authorization.
* これは、最初の認証から 8 時間が経過するまで続きます。
* At this point, when the application attempts to use the refresh token after 8 hours, the request will fail and the application will have to re-initiate an Authorization Code flow that relies on the user's authentication or previously established session.
* この時点で、アプリケーションが 8 時間後にリフレッシュ トークンを使用しようとすると、リクエストは失敗し、アプリケーションはユーザーの認証または以前に確立されたセッションに依存する認可コード フローを再開始する必要があります。
Authorization servers SHOULD link the lifetime of the refresh token to the user's authenticated session with the authorization server. Doing so ensures that when a user logs out, previously issued refresh tokens to browser-based applications become invalid, mimicking a single-logout scenario. Authorization servers MAY set different policies for refresh token issuance, lifetime, and expiration for browser-based applications compared to other public clients.
認可サーバーは、リフレッシュ トークンの有効期間を認可サーバーとのユーザーの認証されたセッションにリンクする必要があります (SHOULD)。これにより、ユーザーがログアウトすると、ブラウザベースのアプリケーションに対して以前に発行された更新トークンが無効になり、シングル ログアウトのシナリオが模倣されます。認可サーバーは、ブラウザベースのアプリケーションのリフレッシュ トークンの発行、有効期間、有効期限について、他のパブリック クライアントとは異なるポリシーを設定してもよい(MAY)。
Since a browser-based application's source code is delivered to the end-user's browser, it is unfit to contain provisioned secrets. As a consequence, browser-based applications are typically deployed as public clients, as defined by Section 2.1 of [RFC6749].
ブラウザベースのアプリケーションのソース コードはエンドユーザーのブラウザに配信されるため、プロビジョニングされたシークレットを含めるには適していません。その結果、[RFC6749] のセクション 2.1 で定義されているように、ブラウザベースのアプリケーションは通常、パブリック クライアントとしてデプロイされます。
Secrets that are statically included as part of an app distributed to multiple users should not be treated as confidential secrets, as one user may inspect their copy and learn the shared secret. For this reason, and those stated in Section 5.3.1 of [RFC6819], authorization servers MUST NOT require client authentication of browser-based applications using a shared secret, as this serves no value beyond client identification, which is already provided by the client_id parameter.
複数のユーザーに配布されるアプリの一部として静的に含まれるシークレットは、1 人のユーザーが自分のコピーを調べて共有シークレットを知る可能性があるため、機密シークレットとして扱うべきではありません。この理由と、[RFC6819] のセクション 5.3.1 に記載されている理由により、認可サーバーは、共有秘密を使用したブラウザベースのアプリケーションのクライアント認証を要求してはなりません (MUST NOT)。共有秘密は、client_id パラメータによってすでに提供されているクライアント識別以上の価値を提供しないからです。
Authorization servers that still require a statically included shared secret for SPA clients MUST treat the client as a public client and not accept the secret as proof of the client's identity. Without additional measures, such clients are subject to client impersonation (see Section 6.3.3.2).
SPA クライアントに静的に含まれる共有シークレットを依然として必要とする認可サーバーは、クライアントをパブリック クライアントとして扱い、クライアントの ID の証明としてシークレットを受け入れてはなりません (MUST)。追加の対策がなければ、そのようなクライアントはクライアントになりすます可能性があります (セクション 6.3.3.2 を参照)。
As stated in Section 10.2 of [RFC6749], the authorization server SHOULD NOT process authorization requests automatically without user consent or interaction, except when the authorization server can assure the identity of the client application.
[RFC6749] のセクション 10.2 に記載されているように、認可サーバーがクライアント アプリケーションの ID を保証できる場合を除き、認可サーバーはユーザーの同意や対話なしに認可リクエストを自動的に処理すべきではありません (SHOULD NOT)。
If authorization servers restrict redirect URIs to a fixed set of absolute HTTPS URIs that prevent the use of wildcard domains, wildcard paths, or wildcard query string components, this exact match of registered absolute HTTPS URIs MAY be accepted by authorization servers as proof of identity of the client for the purpose of deciding whether to automatically process an authorization request when a previous request for the client_id has already been approved.
認可サーバーがリダイレクト URI を、ワイルドカード ドメイン、ワイルドカード パス、またはワイルドカード クエリ文字列コンポーネントの使用を禁止する絶対 HTTPS URI の固定セットに制限する場合、client_id に対する以前のリクエストがすでに承認されている場合に認可リクエストを自動的に処理するかどうかを決定する目的で、登録された絶対 HTTPS URI のこの正確な一致がクライアントの身元証明として認可サーバーによって受け入れられてもよい(MAY)。
Clients MUST register one or more redirect URIs with the authorization server and use only exact registered redirect URIs in the authorization request.
クライアントは 1 つ以上のリダイレクト URI を認可サーバーに登録し、認可リクエストでは正確に登録されたリダイレクト URI のみを使用しなければなりません (MUST)。
Authorization servers MUST require an exact match of a registered redirect URI as described in Section 4.1.1 of [RFC9700]. This helps to prevent attacks targeting the authorization code.
認可サーバーは、[RFC9700] のセクション 4.1.1 に記載されているように、登録されたリダイレクト URI と完全に一致することを要求しなければなりません (MUST)。これは、認証コードをターゲットとした攻撃を防ぐのに役立ちます。
In browser-based applications, it is common to execute the OAuth flow in a secondary window, such as a pop-up or iframe, instead of redirecting the primary window. In these flows, the browser-based app holds control of the primary window, for instance, to avoid page refreshes or to run frame-based flows silently.
ブラウザベースのアプリケーションでは、プライマリ ウィンドウをリダイレクトする代わりに、ポップアップや iframe などのセカンダリ ウィンドウで OAuth フローを実行するのが一般的です。これらのフローでは、ブラウザー ベースのアプリがプライマリ ウィンドウの制御を保持し、たとえばページの更新を回避したり、フレームベースのフローをサイレントで実行したりします。
If the browser-based app and the authorization server are invoked in different frames, they have to use in-browser communication techniques like the postMessage API (a.k.a. [WebMessaging]) instead of top-level redirections. To guarantee confidentiality and authenticity of messages, both the initiator origin and receiver origin of a postMessage MUST be verified using the mechanisms inherently provided by the postMessage API (Section 9.3.2 in [WebMessaging]).
ブラウザベースのアプリと認可サーバーが異なるフレームで呼び出される場合、トップレベルのリダイレクトではなく、postMessage API (別名 [WebMessaging]) のようなブラウザ内通信技術を使用する必要があります。メッセージの機密性と信頼性を保証するために、postMessage の開始元と受信元の両方が、postMessage API ([WebMessaging] のセクション 9.3.2) によって本質的に提供されるメカニズムを使用して検証されなければなりません (MUST)。
Section 4.17 of [RFC9700] provides additional details about the security of in-browser communication flows and the countermeasures that browser-based applications and authorization servers MUST apply to defend against these attacks.
[RFC9700] のセクション 4.17 では、ブラウザ内通信フローのセキュリティと、これらの攻撃を防御するためにブラウザベースのアプリケーションと認可サーバーが適用しなければならない対策についての追加の詳細が提供されています。
In this scenario, the application uses a browser API to send requests to the authorization server and the resource server. Given the nature of OAuth 2.0, these requests are typically cross-origin requests, subjecting them to browser-enforced restrictions on cross-origin communication. The authorization server and the resource server MUST send necessary CORS headers (defined in [Fetch]) to enable the application to make the necessary cross-origin requests. Note that in the extraordinary scenario where the browser-based OAuth client runs in the same origin as the authorization server or resource server, a CORS policy is not needed to enable the necessary interaction.
このシナリオでは、アプリケーションはブラウザー API を使用して、認可サーバーとリソース サーバーにリクエストを送信します。OAuth 2.0 の性質を考慮すると、これらのリクエストは通常クロスオリジン リクエストであり、クロスオリジン通信に対するブラウザ強制の制限が適用されます。認可サーバーとリソースサーバーは、アプリケーションが必要なクロスオリジンリクエストを行えるようにするために、必要な CORS ヘッダー ([Fetch] で定義) を送信しなければなりません (MUST)。ブラウザベースの OAuth クライアントが認可サーバーまたはリソース サーバーと同じオリジンで実行されるという特殊なシナリオでは、必要な対話を有効にするために CORS ポリシーは必要ないことに注意してください。
For the authorization server, the CORS configuration is relevant for the token endpoint, where the browser-based application exchanges the authorization code for tokens. Additionally, if the authorization server provides additional endpoints to the application such as discovery metadata URLs, JSON Web Key Sets, dynamic client registration, revocation, introspection, or user info endpoints, these endpoints may also be accessed by the browser-based application. Consequently, the authorization server is responsible for supporting CORS on these endpoints.
認可サーバーの場合、CORS 構成はトークン エンドポイントに関連しており、ブラウザベースのアプリケーションはトークンの認可コードを交換します。さらに、認可サーバーが、ディスカバリー・メタデータ URL、JSON Web キー・セット、動的クライアント登録、失効、イントロスペクション、ユーザー情報エンドポイントなどの追加のエンドポイントをアプリケーションに提供する場合、ブラウザー・ベースのアプリケーションからもこれらのエンドポイントにアクセスできる可能性があります。したがって、認可サーバーは、これらのエンドポイントで CORS をサポートする責任があります。
This specification does not include guidelines for deciding the concrete CORS policy implementation, which can consist of a wildcard origin or a more restrictive configuration. Note that CORS has two modes of operation with different security properties. The first mode applies to CORS-safelisted requests (formerly known as simple requests), where the browser sends the request and uses the CORS response headers to decide if the response can be exposed to the client-side execution context. For non-CORS-safelisted requests, such as a request with a custom request header, the browser will first check the CORS policy using a preflight. The browser will only send the actual request when the server sends its approval in the preflight response.
この仕様には、具体的な CORS ポリシーの実装を決定するためのガイドラインは含まれていません。CORS ポリシーの実装は、ワイルドカード オリジンまたはより制限的な構成で構成されます。CORS には、セキュリティ プロパティが異なる 2 つの動作モードがあることに注意してください。最初のモードは、CORS セーフリストに登録されたリクエスト (以前はシンプル リクエストと呼ばれていました) に適用されます。このモードでは、ブラウザーがリクエストを送信し、CORS 応答ヘッダーを使用して、応答をクライアント側の実行コンテキストに公開できるかどうかを判断します。カスタム リクエスト ヘッダーを含むリクエストなど、CORS セーフリストに登録されていないリクエストの場合、ブラウザーはまずプリフライトを使用して CORS ポリシーをチェックします。ブラウザは、サーバーがプリフライト応答で承認を送信した場合にのみ、実際のリクエストを送信します。
Note that due to the authorization server's specific configuration, it is possible that the CORS response to a preflight is different from the CORS response to the actual request. During the preflight, the authorization server can only verify the provided origin, but during an actual request, the authorization server has the full request data, such as the client ID. Consequently, the authorization server can approve a known origin during the preflight but reject the actual request after comparing the origin to this specific client's list of pre-registered origins.
認可サーバーの特定の構成により、プリフライトに対する CORS 応答が実際のリクエストに対する CORS 応答と異なる可能性があることに注意してください。プリフライト中、認可サーバーは提供されたオリジンを検証することしかできませんが、実際のリクエスト中は、認可サーバーはクライアント ID などの完全なリクエスト データを保持します。したがって、認可サーバーは、プリフライト中に既知のオリジンを承認しても、そのオリジンをこの特定のクライアントの事前登録オリジンのリストと比較した後、実際のリクエストを拒否することができます。
This section revisits the attack scenarios and consequences from Section 5 and discusses potential additional defenses.
このセクションでは、セクション 5 の攻撃シナリオとその結果を再検討し、追加の防御策の可能性について説明します。
If the attacker has the ability to execute malicious code in the application's execution context, the following attack scenarios become relevant:
攻撃者がアプリケーションの実行コンテキストで悪意のあるコードを実行できる場合、次の攻撃シナリオが関連します。
* Single-Execution Token Theft (Section 5.1.1)
* 単一実行トークンの盗難 (セクション 5.1.1)
* Persistent Token Theft (Section 5.1.2)
* 永続的なトークンの盗難 (セクション 5.1.2)
* Acquisition and Extraction of New Tokens (Section 5.1.3)
* 新しいトークンの取得と抽出 (セクション 5.1.3)
* Proxying Requests via the User's Browser (Section 5.1.4)
* ユーザーのブラウザを介したリクエストのプロキシ (セクション 5.1.4)
The most dangerous attack scenario is the acquisition and extraction of new tokens. In this attack scenario, the attacker only interacts with the authorization server, which makes the actual implementation details of the OAuth functionality in the client irrelevant. Even if the legitimate client application finds a way to completely isolate the tokens from the attacker, the attacker will still be able to obtain tokens from the authorization server.
最も危険な攻撃シナリオは、新しいトークンの取得と抽出です。この攻撃シナリオでは、攻撃者は認可サーバーとのみ対話するため、クライアントの OAuth 機能の実際の実装の詳細は無関係になります。たとえ正規のクライアント アプリケーションが攻撃者からトークンを完全に隔離する方法を見つけたとしても、攻撃者は依然として認可サーバーからトークンを取得できます。
Note that these attack scenarios result in the following consequences:
これらの攻撃シナリオは次の結果をもたらすことに注意してください。
* Exploiting Stolen Refresh Tokens (Section 5.2.1)
* 盗まれたリフレッシュ トークンの悪用 (セクション 5.2.1)
* Exploiting Stolen Access Tokens (Section 5.2.2)
* 盗まれたアクセストークンの悪用 (セクション 5.2.2)
* Client Hijacking (Section 5.2.3)
* クライアントハイジャック (セクション 5.2.3)
While this architecture is inherently vulnerable to malicious browser-based code, there are some additional defenses that can help to increase the security posture of the application. Note that none of these defenses address or fix the underlying problem that allows the attacker to run a new flow to obtain tokens.
このアーキテクチャは本質的に悪意のあるブラウザベースのコードに対して脆弱ですが、アプリケーションのセキュリティ体制を強化するのに役立つ追加の防御機能がいくつかあります。これらの防御策はどれも、攻撃者が新しいフローを実行してトークンを取得できるようにする根本的な問題に対処したり修正したりするものではないことに注意してください。
When handling tokens directly, the application can choose different storage mechanisms to store access tokens and refresh tokens. Universally accessible storage areas, such as _Local Storage_ [WebStorage], are easier to access from malicious JavaScript than more isolated storage areas, such as a _Web Worker_ [WebWorker]. Section 8 discusses different storage mechanisms with their trade-off in more detail.
トークンを直接処理する場合、アプリケーションはアクセス トークンとリフレッシュ トークンを保存するためにさまざまなストレージ メカニズムを選択できます。_Local Storage_ [WebStorage] などの普遍的にアクセス可能なストレージ領域は、_Web Worker_ [WebWorker] などのより分離されたストレージ領域よりも、悪意のある JavaScript からアクセスするのが簡単です。セクション 8 では、さまざまなストレージ メカニズムとそのトレードオフについて詳しく説明します。
A practical implementation pattern can use a Web Worker [WebWorker] to isolate the refresh token and provide the application with the access token making requests to resource servers. This prevents an attacker from using the application's refresh token to obtain new tokens.
実際の実装パターンでは、Web ワーカー [WebWorker] を使用してリフレッシュ トークンを分離し、リソース サーバーにリクエストを行うアクセス トークンをアプリケーションに提供できます。これにより、攻撃者がアプリケーションの更新トークンを使用して新しいトークンを取得することができなくなります。
However, even a token storage mechanism that completely isolates the tokens from the attacker does not prevent the attacker from running a new flow to obtain a fresh set of tokens (see Section 5.1.3).
ただし、攻撃者からトークンを完全に隔離するトークン ストレージ メカニズムであっても、攻撃者が新しいトークンのセットを取得するために新しいフローを実行することは妨げられません (セクション 5.1.3 を参照)。
Browser-based OAuth clients can implement DPoP [RFC9449] to transition from bearer access tokens and bearer refresh tokens to sender-constrained tokens. In such an implementation, the private key used to sign DPoP proofs is handled by the browser (a non-extractable [CryptoKeyPair] is stored using [W3C.IndexedDB]). As a result, the use of DPoP effectively prevents scenarios where the XSS attacker exfiltrates the application's tokens (see Sections 5.1.1 and 5.1.2).
ブラウザベースの OAuth クライアントは、DPoP [RFC9449] を実装して、ベアラー アクセス トークンおよびベアラー リフレッシュ トークンから送信者制約トークンに移行できます。このような実装では、DPoP 証明の署名に使用される秘密鍵はブラウザによって処理されます (抽出不可能な [CryptoKeyPair] は [W3C.IndexedDB] を使用して保存されます)。結果として、DPoP の使用は、XSS 攻撃者がアプリケーションのトークンを窃取するシナリオを効果的に防止します (セクション 5.1.1 および 5.1.2 を参照)。
Note that the use of DPoP does not prevent the attacker from running a new flow to obtain a fresh access token (and optionally a refresh token); see Section 5.1.3. Even when DPoP is mandatory, the attacker can bind the fresh set of tokens to a key pair under their control, allowing them to exfiltrate the sender-constrained tokens and use them by relying on the attacker-controlled key to calculate the necessary DPoP proofs.
DPoP を使用しても、攻撃者が新しいフローを実行して新しいアクセス トークン (および必要に応じてリフレッシュ トークン) を取得することは妨げられないことに注意してください。セクション5.1.3を参照してください。DPoP が必須の場合でも、攻撃者は新しいトークンのセットを自分の制御下の鍵ペアにバインドすることができ、送信者が制約されたトークンを抽出し、攻撃者が制御する鍵に依存してトークンを使用して、必要な DPoP 証明を計算することができます。
The scenario where the attacker obtains a fresh access token and (optionally refresh token) Section 5.1.3 relies on the ability to directly interact with the authorization server from within the browser. In theory, a defense that prevents the attacker from silently interacting with the authorization server could solve the most dangerous attack scenario. However, in practice, such defenses are ineffective or impractical.
攻撃者が新しいアクセス トークンと (オプションでリフレッシュ トークン) セクション 5.1.3 を取得するシナリオは、ブラウザ内から認可サーバーと直接対話する機能に依存しています。理論的には、攻撃者がサイレントに認可サーバーと対話するのを防ぐ防御があれば、最も危険な攻撃シナリオを解決できる可能性があります。しかし、実際には、そのような防御は効果がないか、非現実的です。
For completeness, this BCP lists a few options below. Note that none of these defenses is recommended, as they do not offer practically usable security benefits.
完全を期すために、この BCP では以下にいくつかのオプションを示します。これらの防御策はいずれも、実際に使用可能なセキュリティ上の利点を提供しないため、推奨されないことに注意してください。
The authorization server could block authorization requests that originate from within an iframe. While this would prevent the exact scenario from Section 5.1.3, it would not work for slight variations of the attack scenario. For example, the attacker can launch the silent flow in a pop-up window or a pop-under window. Additionally, browser-only OAuth clients typically rely on a hidden iframe-based flow to bootstrap the user's authentication state, so this approach would significantly impact the user experience.
認可サーバーは、iframe 内から発信される認可リクエストをブロックする可能性があります。これにより、セクション 5.1.3 の正確なシナリオは回避されますが、攻撃シナリオがわずかに異なる場合には機能しません。たとえば、攻撃者はポップアップ ウィンドウやポップアンダー ウィンドウでサイレント フローを起動する可能性があります。さらに、ブラウザ専用の OAuth クライアントは通常、ユーザーの認証状態をブートストラップするために非表示の iframe ベースのフローに依存するため、このアプローチはユーザー エクスペリエンスに大きな影響を与えます。
The authorization server could opt to make user consent mandatory in every Authorization Code flow (as described in Section 10.2 of [RFC6749]), thus requiring user interaction before issuing an authorization code. This approach would make it harder for an attacker to run a silent flow to obtain a fresh set of tokens. However, it also significantly impacts the user experience by continuously requiring consent. As a result, this approach would result in "consent fatigue", which makes it likely that the user will blindly approve the consent, even when it is associated with a flow that was initiated by the attacker.
認可サーバーは、([RFC6749] のセクション 10.2 で説明されているように) すべての認可コード フローでユーザーの同意を必須にすることを選択できるため、認可コードを発行する前にユーザーの対話が必要になります。このアプローチにより、攻撃者がサイレント フローを実行して新しいトークン セットを取得することが困難になります。ただし、同意を継続的に要求するため、ユーザー エクスペリエンスにも大きな影響を与えます。結果として、このアプローチでは「同意疲労」が発生し、攻撃者によって開始されたフローに関連付けられている場合でも、ユーザーが同意を盲目的に承認する可能性が高くなります。
To summarize, the architecture of a browser-based OAuth client application is straightforward but results in a significant increase in the attack surface of the application. The attacker is not only able to hijack the client but is also able to extract a full-featured set of tokens from the browser-based application.
要約すると、ブラウザベースの OAuth クライアント アプリケーションのアーキテクチャは単純ですが、アプリケーションの攻撃対象領域が大幅に増加します。攻撃者はクライアントをハイジャックできるだけでなく、ブラウザベースのアプリケーションからフル機能のトークンのセットを抽出することもできます。
This architecture is not recommended for business applications, sensitive applications, and applications that handle personal data.
このアーキテクチャは、ビジネス アプリケーション、機密性の高いアプリケーション、個人データを扱うアプリケーションには推奨されません。
Client applications and backend applications have evolved significantly over the last two decades, along with threats, attacker models, and a general understanding of modern application security. As a result, previous recommendations generally accepted in the industry as well as published by the OAuth Working Group are often no longer recommended, and proposed solutions often fall short of meeting the expected security requirements.
クライアント アプリケーションとバックエンド アプリケーションは、脅威、攻撃者モデル、最新のアプリケーション セキュリティの一般的な理解とともに、過去 20 年間で大幅に進化してきました。その結果、業界で一般に受け入れられている以前の推奨事項や OAuth Working Group によって発行された推奨事項は、推奨されなくなることが多く、提案されたソリューションが期待されるセキュリティ要件を満たしていないことがよくあります。
This section discusses a few alternative architecture patterns, which are not recommended for use in modern browser-based OAuth applications. This section discusses each of the patterns along with a threat analysis that investigates the attack scenarios and consequences when relevant.
このセクションでは、最新のブラウザベースの OAuth アプリケーションでの使用が推奨されない、いくつかの代替アーキテクチャ パターンについて説明します。このセクションでは、各パターンについて、攻撃シナリオと関連する場合の結果を調査する脅威分析について説明します。
Too often, simple applications are made needlessly complex by using OAuth to replace the concept of session management. A typical example is the modern incarnation of a server-side Model-View-Controller (MVC) application, which now consists of a browser-based frontend backed by a server-side API.
OAuth を使用してセッション管理の概念を置き換えることにより、単純なアプリケーションが不必要に複雑になることがよくあります。典型的な例は、サーバー側 Model-View-Controller (MVC) アプリケーションの最新の具体化であり、現在はサーバー側 API をサポートするブラウザー ベースのフロントエンドで構成されています。
In such an application, the use of OpenID Connect to offload user authentication to a dedicated provider can significantly simplify the application's architecture and development. However, the use of OAuth for governing access between the frontend and the backend is often not needed. Instead of using access tokens, the application can rely on server-side cookie-based session state to keep track of the user's authentication status. The security guidelines to protect the session cookie are discussed in Section 6.1.3.2.
このようなアプリケーションでは、OpenID Connect を使用してユーザー認証を専用プロバイダーにオフロードすると、アプリケーションのアーキテクチャと開発を大幅に簡素化できます。ただし、フロントエンドとバックエンドの間のアクセスを管理するために OAuth を使用する必要がない場合がよくあります。アクセス トークンを使用する代わりに、アプリケーションはサーバー側の Cookie ベースのセッション状態に依存して、ユーザーの認証ステータスを追跡できます。セッション Cookie を保護するためのセキュリティ ガイドラインについては、セクション 6.1.3.2 で説明します。
While the advice to not use OAuth seems out of place in this document, it is important to note that OAuth was originally created for third-party or federated access to APIs, so it may not be the best solution in a single common-domain deployment. That said, there are still some advantages in using OAuth even in a common-domain architecture, such as:
OAuth を使用しないというアドバイスはこのドキュメントでは場違いに思えますが、OAuth はもともと API へのサードパーティまたはフェデレーション アクセスのために作成されたものであるため、単一の共通ドメインの展開では最適なソリューションではない可能性があることに注意することが重要です。そうは言っても、共通ドメイン アーキテクチャであっても OAuth を使用することには、次のようないくつかの利点があります。
* Allowing more flexibility in the future. For example, if you were to later add a new domain to the system, having OAuth already in place means that a new domain wouldn't require any additional rearchitecting.
* 将来的にはより柔軟な対応が可能になります。たとえば、後でシステムに新しいドメインを追加する場合、OAuth がすでに導入されているということは、新しいドメインに追加の再設計が必要ないことを意味します。
* Being able to take advantage of existing library support rather than writing bespoke code for the integration.
* 統合用にオーダーメイドのコードを作成するのではなく、既存のライブラリ サポートを利用できるようになります。
* Centralizing login and multi-factor authentication support, account management, and recovery at the OAuth server rather than making it part of the application logic.
* ログインと多要素認証のサポート、アカウント管理、リカバリをアプリケーション ロジックの一部にするのではなく、OAuth サーバーで一元化します。
* Splitting responsibilities between authenticating a user and serving resources.
* ユーザーの認証とリソースの提供の間で責任を分割します。
Using OAuth for browser-based applications in a first-party same-domain scenario provides these advantages and can be accomplished by any of the architectural patterns described above.
ファーストパーティの同一ドメイン シナリオでブラウザ ベースのアプリケーションに OAuth を使用すると、これらの利点が得られ、上記のアーキテクチャ パターンのいずれかによって実現できます。
Due to the lack of using OAuth, this architecture pattern is only vulnerable to the following attack scenario: proxying requests via the user's browser (Section 5.1.4). As a result, this pattern can lead to the following consequence: client hijacking (Section 5.2.3).
OAuth を使用していないため、このアーキテクチャ パターンは次の攻撃シナリオに対してのみ脆弱です: ユーザーのブラウザを介したリクエストのプロキシ (セクション 5.1.4)。結果として、このパターンは次の結果を引き起こす可能性があります: クライアントのハイジャック (セクション 5.2.3)。
The OAuth 2.0 Implicit grant type (defined in Section 4.2 of [RFC6749]) works by the authorization server issuing an access token in the authorization response (front channel) without an authorization code exchange step. In this case, the access token is returned in the fragment part of the redirect URI, providing an attacker with several opportunities to intercept and steal the access token.
OAuth 2.0 暗黙的許可タイプ ([RFC6749] のセクション 4.2 で定義) は、認可サーバーが認可コード交換ステップなしで認可応答 (フロント チャネル) でアクセス トークンを発行することによって機能します。この場合、アクセス トークンはリダイレクト URI のフラグメント部分で返され、攻撃者にアクセス トークンを傍受して盗む機会を複数与えます。
The security properties of the Implicit grant type make it no longer a recommended best practice. To effectively prevent the use of this flow, the authorization server MUST NOT issue access tokens in the authorization response and MUST issue access tokens only from the token endpoint. Browser-based clients MUST use the Authorization Code grant type and MUST NOT use the Implicit grant type to obtain access tokens.
暗黙的付与タイプのセキュリティ特性により、これは推奨されるベスト プラクティスではなくなりました。このフローの使用を効果的に防止するには、認可サーバーは認可応答でアクセス トークンを発行してはならず、トークン エンドポイントからのみアクセス トークンを発行しなければなりません。ブラウザベースのクライアントは、アクセス トークンを取得するために認証コード付与タイプを使用しなければならず、暗黙的付与タイプを使用してはなりません。
Historically, the Implicit grant type provided an advantage to browser-based applications since JavaScript could always arbitrarily read and manipulate the fragment portion of the URL without triggering a page reload. This was necessary in order to remove the access token from the URL after it was obtained by the app. Additionally, until CORS was widespread in browsers, the Implicit grant type offered an alternative flow that didn't require CORS support in the browser or on the server.
これまで、JavaScript はページのリロードをトリガーせずに URL のフラグメント部分を常に任意に読み取って操作できたため、暗黙的な許可タイプはブラウザベースのアプリケーションに利点をもたらしました。これは、アプリがアクセス トークンを取得した後、URL からアクセス トークンを削除するために必要でした。さらに、CORS がブラウザーで普及するまでは、暗黙的な許可タイプによって、ブラウザーまたはサーバーでの CORS サポートを必要としない代替フローが提供されていました。
Modern browsers now have the Session History API (described in "Navigation and session history" of [HTML]), which provides a mechanism to modify the path and query string component of the URL without triggering a page reload. Additionally, CORS has widespread support and is often used by single-page applications for many purposes. This means modern browser-based applications can use the OAuth 2.0 Authorization Code grant type with PKCE, since they have the ability to remove the authorization code from the query string without triggering a page reload thanks to the Session History API, and CORS support at the token endpoint means the app can obtain tokens even if the authorization server is on a different domain.
最近のブラウザには、セッション履歴 API ([HTML] の「ナビゲーションとセッション履歴」で説明) が備わっており、ページのリロードをトリガーせずに URL のパスとクエリ文字列コンポーネントを変更するメカニズムを提供します。さらに、CORS は広範囲にサポートされており、単一ページ アプリケーションでさまざまな目的でよく使用されます。これは、最新のブラウザベースのアプリケーションが PKCE で OAuth 2.0 認証コード付与タイプを使用できることを意味します。これは、セッション履歴 API のおかげで、ページのリロードをトリガーせずにクエリ文字列から認証コードを削除できるためです。また、トークン エンドポイントでの CORS サポートにより、認証サーバーが別のドメインにある場合でもアプリはトークンを取得できます。
The architecture pattern discussed in this section is vulnerable to the following attack scenarios:
このセクションで説明するアーキテクチャ パターンは、次の攻撃シナリオに対して脆弱です。
* Single-Execution Token Theft (Section 5.1.1)
* 単一実行トークンの盗難 (セクション 5.1.1)
* Persistent Token Theft (Section 5.1.2)
* 永続的なトークンの盗難 (セクション 5.1.2)
* Acquisition and Extraction of New Tokens (Section 5.1.3)
* 新しいトークンの取得と抽出 (セクション 5.1.3)
* Proxying Requests via the User's Browser (Section 5.1.4)
* ユーザーのブラウザを介したリクエストのプロキシ (セクション 5.1.4)
As a result, this pattern can lead to the following consequences:
結果として、このパターンでは次のような結果が生じる可能性があります。
* Exploiting Stolen Refresh Tokens (Section 5.2.1)
* 盗まれたリフレッシュ トークンの悪用 (セクション 5.2.1)
* Exploiting Stolen Access Tokens (Section 5.2.2)
* 盗まれたアクセストークンの悪用 (セクション 5.2.2)
* Client Hijacking (Section 5.2.3)
* クライアントハイジャック (セクション 5.2.3)
Apart from the attack scenarios and consequences that were already discussed, there are a few additional attacks that further support the deprecation of the Implicit grant type. Many attacks on the Implicit grant type described by [RFC6819] and Section 4.1.2 of [RFC9700] do not have sufficient mitigation strategies. The following sections describe the specific attacks that cannot be mitigated while continuing to use the Implicit grant type.
すでに説明した攻撃シナリオと結果とは別に、暗黙的許可タイプの非推奨をさらに裏付ける追加の攻撃がいくつかあります。[RFC6819] および [RFC9700] のセクション 4.1.2 で説明されている暗黙的許可タイプに対する攻撃の多くには、十分な緩和戦略がありません。次のセクションでは、暗黙的な許可タイプを使用し続けている間に軽減できない特定の攻撃について説明します。
If an attacker is able to cause the authorization response to be sent to a URI under their control, they will get access directly to the authorization response including the access token. Several methods of performing this attack are described in detail in [RFC9700].
攻撃者が自分の制御下の URI に認可応答を送信させることができた場合、攻撃者はアクセス トークンを含む認可応答に直接アクセスできるようになります。この攻撃を実行するいくつかの方法は [RFC9700] で詳細に説明されています。
An attacker could obtain the access token from the browser's history. The countermeasures recommended in [RFC6819] are limited to using short expiration times for tokens and indicate that browsers should not cache the response. Neither of these fully prevent this attack; they only reduce the potential damage.
攻撃者はブラウザの履歴からアクセス トークンを取得する可能性があります。[RFC6819] で推奨されている対策は、トークンの有効期限を短くすることに限定されており、ブラウザは応答をキャッシュすべきではないとしています。どちらもこの攻撃を完全に防ぐことはできません。潜在的なダメージを軽減するだけです。
Additionally, many browsers now also sync browser history to cloud services and to multiple devices, providing an even wider attack surface to extract access tokens out of the URL.
さらに、多くのブラウザーは現在、ブラウザーの履歴をクラウド サービスや複数のデバイスと同期しており、URL からアクセス トークンを抽出するためのさらに広い攻撃対象領域を提供しています。
This is discussed in more detail in Section 4.3.2 of [RFC9700].
これについては、[RFC9700] のセクション 4.3.2 で詳しく説明されています。
An attacker could modify the page or inject scripts into the browser through various means, including when the browser's HTTPS connection is being intercepted by, for example, a corporate network. While attacks on the TLS layer are typically out of scope of basic security recommendations to prevent, in the case of browser-based applications, they are much easier to perform. An injected script can enable an attacker to have access to everything on the page.
攻撃者は、ブラウザの HTTPS 接続が企業ネットワークなどによって傍受されている場合など、さまざまな手段を通じてページを変更したり、ブラウザにスクリプトを挿入したりする可能性があります。TLS 層に対する攻撃は通常、防止すべき基本的なセキュリティ推奨事項の範囲外ですが、ブラウザベースのアプリケーションの場合、実行ははるかに簡単です。挿入されたスクリプトにより、攻撃者がページ上のあらゆるものにアクセスできるようになる可能性があります。
The risk of a malicious script running on the page may be amplified when the application uses a known standard way of obtaining access tokens; namely, the attacker can always look at the window.location variable to find an access token. This threat profile is different from an attacker specifically targeting an individual application by knowing where or how an access token obtained via the Authorization Code flow may end up being stored.
アプリケーションがアクセス トークンを取得する既知の標準的な方法を使用する場合、ページ上で悪意のあるスクリプトが実行されるリスクが増幅される可能性があります。つまり、攻撃者はいつでも window.location 変数を調べてアクセス トークンを見つけることができます。この脅威プロファイルは、認証コード フローを介して取得されたアクセス トークンが最終的にどこにどのように保存されるかを知ることで、個々のアプリケーションを特にターゲットにする攻撃者とは異なります。
It is relatively common to use third-party scripts in browser-based applications, such as analytics tools, crash reporting, and even things like a social media "like" button. In these situations, the author of the application may not be able to be fully aware of the entirety of the code running in the application. When an access token is returned in the fragment, it is visible to any third-party scripts on the page.
分析ツール、クラッシュレポート、さらにはソーシャルメディアの「いいね!」ボタンなど、ブラウザベースのアプリケーションでサードパーティのスクリプトを使用することは比較的一般的です。このような状況では、アプリケーションの作成者は、アプリケーション内で実行されているコード全体を完全には認識できない可能性があります。アクセス トークンがフラグメントで返されると、ページ上のすべてのサードパーティ スクリプトからアクセス トークンが表示されます。
There are several additional reasons the Implicit grant type is disadvantageous compared to using the recommended Authorization Code grant type.
推奨される認可コード付与タイプを使用する場合と比較して、暗黙的付与タイプが不利になる理由は他にもいくつかあります。
* OAuth 2.0 provides no mechanism for a client to verify that a particular access token was intended for that client, which could lead to misuse and possible impersonation attacks if a malicious party hands off an access token it retrieved through some other means to the client.
* OAuth 2.0 には、特定のアクセス トークンがそのクライアントを対象としたものであるかどうかをクライアントが検証するメカニズムが用意されていないため、悪意のある当事者が他の手段で取得したアクセス トークンをクライアントに渡すと、悪用やなりすまし攻撃が発生する可能性があります。
* Returning an access token in the front-channel redirect gives the authorization server no assurance that the access token will actually end up at the application, since there are many ways this redirect may fail or be intercepted.
* フロントチャネル リダイレクトでアクセス トークンを返すと、このリダイレクトが失敗したり傍受されたりする可能性が多数あるため、認可サーバーはアクセス トークンが実際にアプリケーションに届くという保証がありません。
* Supporting the Implicit grant type requires additional code, more upkeep and understanding of the related security considerations. Limiting the authorization server to just the Authorization Code grant type reduces the attack surface of the implementation.
* 暗黙的な許可タイプをサポートするには、追加のコード、より多くのメンテナンス、および関連するセキュリティ上の考慮事項の理解が必要です。認可サーバーを認可コード付与タイプのみに制限すると、実装の攻撃対象領域が減少します。
* If the browser-based application gets wrapped into a native app, then [RFC8252] also requires the use of the Authorization Code grant type with PKCE anyway.
* ブラウザベースのアプリケーションがネイティブ アプリケーションにラップされる場合、[RFC8252] ではとにかく PKCE で認可コード付与タイプを使用することも要求しています。
The Resource Owner Password Credentials Grant MUST NOT be used, as described in Section 2.4 of [RFC9700]. Instead, using the Authorization Code grant type and redirecting the user to the authorization server provides the authorization server the opportunity to prompt the user for secure non-phishable authentication options, take advantage of single sign-on sessions, or use third-party identity providers. In contrast, the Resource Owner Password Credentials Grant does not provide any built-in mechanism for these and would instead need to be extended with custom protocols.
[RFC9700] のセクション 2.4 に記載されているように、リソース所有者パスワード認証情報付与は使用してはなりません (MUST NOT)。代わりに、認可コード付与タイプを使用してユーザーを認可サーバーにリダイレクトすると、認可サーバーはユーザーに安全なフィッシング不可能な認証オプションの入力を求めたり、シングル サインオン セッションを利用したり、サードパーティの ID プロバイダーを使用したりする機会を提供します。対照的に、リソース所有者パスワード認証情報付与には、これらに対する組み込みメカニズムが提供されていないため、代わりにカスタム プロトコルを使用して拡張する必要があります。
To conform to this best practice, browser-based applications using OAuth or OpenID Connect MUST use a redirect-based flow (e.g., the OAuth Authorization Code grant type) as described in this document.
このベストプラクティスに準拠するには、OAuth または OpenID Connect を使用するブラウザベースのアプリケーションは、このドキュメントで説明されているように、リダイレクトベースのフロー (OAuth 認証コード付与タイプなど) を使用しなければなりません (MUST)。
In an attempt to limit the attacker's ability to extract existing tokens or acquire a new set of tokens, a pattern using a Service Worker [W3C.service-workers] has been suggested in the past. In this pattern, the application's first action upon loading is registering a Service Worker. The Service Worker becomes responsible for executing the Authorization Code flow to obtain tokens and to augment outgoing requests to the resource server with the proper access token. Additionally, the Service Worker blocks the client application's code from making direct calls to the authorization server's endpoints. This restriction aims to target the attack scenario "Acquisition and Extraction of New Tokens" (Section 5.1.3).
既存のトークンを抽出したり、新しいトークンのセットを取得したりする攻撃者の能力を制限する試みとして、サービス ワーカー [W3C.service-workers] を使用するパターンが過去に提案されました。このパターンでは、アプリケーションのロード時の最初のアクションは Service Worker の登録です。Service Worker は、認可コード フローを実行してトークンを取得し、適切なアクセス トークンを使用してリソース サーバーへの送信リクエストを強化する責任を負います。さらに、Service Worker は、クライアント アプリケーションのコードが認可サーバーのエンドポイントを直接呼び出すのをブロックします。この制限は、「新しいトークンの取得と抽出」(セクション 5.1.3) という攻撃シナリオをターゲットにすることを目的としています。
The sequence diagram included below illustrates the interactions between the client, the Service Worker, the authorization server, and the resource server.
以下に含まれるシーケンス図は、クライアント、Service Worker、認可サーバー、およびリソース サーバー間の対話を示しています。
Service Resource Authorization
User Application Worker Server Server
| | | | |
| browse | | | |
|----------->| | | |
| |----------->| | /authorize |
| | |---------------------------------->|
| | | redirect w/ authorization code |
| | |< - - - - - - - - - - - - - - - - -|
| | | | |
| | | token request | |
| | | w/ auth code | /token |
| | |---------------------------------->|
| | |< - - - - - - - - - - - - - - - - -|
| | | | |
| | resource | | |
| | request | | |
| |----------->| | |
| | | resource request | |
| | | w/ access token | |
| | |------------------->| |
| | | | |
User Application Service Resource Authorization
Worker Server Server
Figure 4: OAuth 2.0 Service Worker Pattern
図 4: OAuth 2.0 Service Worker パターン
Note that this pattern never exposes the tokens to the application running in the browser. Since the Service Worker runs in an isolated execution environment, there is no shared memory and no way for the client application to influence the execution of the Service Worker.
このパターンでは、ブラウザーで実行されているアプリケーションにトークンが公開されることはありません。Service Worker は分離された実行環境で実行されるため、共有メモリがなく、クライアント アプリケーションが Service Worker の実行に影響を与える方法はありません。
The architecture pattern discussed in this section is vulnerable to the following attack scenarios:
このセクションで説明するアーキテクチャ パターンは、次の攻撃シナリオに対して脆弱です。
* Acquisition and Extraction of New Tokens (Section 5.1.3)
* 新しいトークンの取得と抽出 (セクション 5.1.3)
* Proxying Requests via the User's Browser (Section 5.1.4)
* ユーザーのブラウザを介したリクエストのプロキシ (セクション 5.1.4)
As a result, this pattern can lead to the following consequences:
結果として、このパターンは次のような結果を引き起こす可能性があります。
* Exploiting Stolen Refresh Tokens (Section 5.2.1)
* 盗まれたリフレッシュ トークンの悪用 (セクション 5.2.1)
* Exploiting Stolen Access Tokens (Section 5.2.2)
* 盗まれたアクセストークンの悪用 (セクション 5.2.2)
* Client Hijacking (Section 5.2.3)
* クライアントハイジャック (セクション 5.2.3)
The seemingly promising security benefits of using a Service Worker warrant a more detailed discussion of its security limitations. To fully protect the application against the relevant attack scenarios (Section 5.1), the Service Worker needs to meet two security requirements:
Service Worker を使用すると、一見有望なセキュリティ上の利点があるため、そのセキュリティ上の制限についてさらに詳しく説明する必要があります。関連する攻撃シナリオ (セクション 5.1) からアプリケーションを完全に保護するには、Service Worker は次の 2 つのセキュリティ要件を満たす必要があります。
1. Prevent an attacker from exfiltrating tokens.
1. 攻撃者がトークンを持ち出すのを防ぎます。
2. Prevent an attacker from acquiring a new set of tokens.
2. 攻撃者が新しいトークンのセットを取得できないようにします。
Once registered, the Service Worker runs an Authorization Code flow and obtains the tokens. Since the Service Worker keeps track of tokens in its own isolated execution environment, they are out of reach for any application code, including potentially malicious code. Consequently, the Service Worker meets the first requirement of preventing token exfiltration. This essentially neutralizes the first two attack scenarios discussed in Section 5.1.
登録後、Service Worker は認証コード フローを実行し、トークンを取得します。Service Worker は独自の分離された実行環境でトークンを追跡するため、潜在的に悪意のあるコードを含むアプリケーション コードはトークンにアクセスできません。その結果、Service Worker はトークンの流出を防ぐという最初の要件を満たします。これにより、セクション 5.1 で説明した最初の 2 つの攻撃シナリオが基本的に無力化されます。
To meet the second security requirement, the Service Worker must be able to guarantee that an attacker controlling the legitimate application cannot execute a new Authorization Code grant; this attack is discussed in Section 5.1.3. Due to the nature of Service Workers, the registered Service Worker will be able to block all outgoing requests that initiate such a new flow, even when they occur in a frame or a new window.
2 番目のセキュリティ要件を満たすには、Service Worker は、正規のアプリケーションを制御する攻撃者が新しい認可コード付与を実行できないことを保証できなければなりません。この攻撃についてはセクション 5.1.3 で説明します。Service Worker の性質により、登録された Service Worker は、フレームまたは新しいウィンドウで発生した場合でも、そのような新しいフローを開始するすべての発信リクエストをブロックできます。
However, the malicious code running inside the application can unregister this Service Worker. Unregistering a Service Worker can have a significant functional impact on the application, so it is not an operation the browser handles lightly. Therefore, an unregistered Service Worker is marked as such, but all currently running instances remain active until their corresponding browsing context is terminated (e.g., by closing the tab or window). So even when an attacker unregisters a Service Worker, it remains active and able to prevent the attacker from reaching the authorization server.
ただし、アプリケーション内で実行されている悪意のあるコードによって、この Service Worker の登録が解除される可能性があります。Service Worker の登録解除は、アプリケーションの機能に重大な影響を与える可能性があるため、ブラウザーが簡単に処理できる操作ではありません。したがって、未登録の Service Worker はそのようにマークされますが、現在実行中のすべてのインスタンスは、対応する閲覧コンテキストが終了するまで (タブやウィンドウを閉じるなど) アクティブのままになります。そのため、攻撃者が Service Worker の登録を解除した場合でも、Service Worker はアクティブなままとなり、攻撃者が認可サーバーに到達するのを防ぐことができます。
One of the consequences of unregistering a Service Worker is that it will not be present when a new browsing context is opened. So when the attacker first unregisters the Service Worker and then starts a new flow in a frame, there will be no Service Worker associated with the browsing context of the frame. Consequently, the attacker will be able to run its own new Authorization Code grant, extract the authorization code from the frame's URL, and exchange it for tokens. In essence, the Service Worker fails to meet the second security requirement, leaving it vulnerable to the scenario where the attacker acquires a new set of tokens (Section 5.1.3).
Service Worker の登録を解除すると、新しい閲覧コンテキストが開かれたときに Service Worker が存在しなくなります。したがって、攻撃者が最初に Service Worker の登録を解除し、次にフレーム内で新しいフローを開始すると、フレームの閲覧コンテキストに関連付けられた Service Worker は存在しなくなります。その結果、攻撃者は独自の新しい認証コード付与を実行し、フレームの URL から認証コードを抽出し、それをトークンと交換することができます。基本的に、Service Worker は 2 番目のセキュリティ要件を満たしていないため、攻撃者が新しいトークンのセットを取得するシナリオに対して脆弱なままになります (セクション 5.1.3)。
Due to these shortcomings, combined with the significant complexity of registering and maintaining a Service Worker, this pattern is not recommended.
これらの欠点と、Service Worker の登録と維持の非常に複雑なため、このパターンはお勧めできません。
Finally, note that the use of a Service Worker by itself does not increase the attack surface of the application. In practice, Service Workers are often used to retrofit a legacy application with support for including OAuth access tokens on outgoing requests. The Service Worker in these scenarios does not change the security properties of the application but merely simplifies development and maintenance of the application.
最後に、Service Worker を単独で使用しても、アプリケーションの攻撃対象領域が増加するわけではないことに注意してください。実際には、Service Worker は、発信リクエストに OAuth アクセス トークンを含めるサポートを備えたレガシー アプリケーションを改修するためによく使用されます。これらのシナリオの Service Worker は、アプリケーションのセキュリティ プロパティを変更するのではなく、単にアプリケーションの開発とメンテナンスを簡素化するだけです。
When a browser-based application handles OAuth access tokens or refresh tokens directly, it becomes responsible for ephemerally or persistently storing the tokens. As a consequence, the application needs to decide how to manage the tokens (e.g., in-memory vs. persistent storage) and which steps to take to further isolate the tokens from the main application code. This section discusses a few different storage mechanisms and their properties. These recommendations take into account the unique properties of OAuth tokens, some of which may overlap with general browser security recommendations.
ブラウザベースのアプリケーションが OAuth アクセス トークンまたはリフレッシュ トークンを直接処理する場合、トークンを一時的または永続的に保存する必要があります。その結果、アプリケーションはトークンを管理する方法 (メモリ内か永続ストレージなど) と、メインのアプリケーション コードからトークンをさらに分離するためにどの手順を実行するかを決定する必要があります。このセクションでは、いくつかの異なるストレージ メカニズムとそのプロパティについて説明します。これらの推奨事項では、OAuth トークンの固有のプロパティが考慮されており、その一部は一般的なブラウザーのセキュリティ推奨事項と重複する可能性があります。
When discussing the security properties of browser-based token storage solutions, it is important to understand the attacker's capabilities when they compromise a browser-based application. Similar to previous discussions, two main attack scenarios should be taken into account:
ブラウザベースのトークン ストレージ ソリューションのセキュリティ特性について議論する場合、ブラウザベースのアプリケーションを侵害する際の攻撃者の能力を理解することが重要です。これまでの議論と同様に、次の 2 つの主な攻撃シナリオを考慮する必要があります。
1. The attacker obtaining tokens from storage.
1. 攻撃者はストレージからトークンを取得します。
2. The attacker obtaining tokens from the provider (e.g., the authorization server or the token-mediating backend).
2. 攻撃者はプロバイダー (認可サーバーやトークン仲介バックエンドなど) からトークンを取得します。
Since the attacker's code becomes indistinguishable from the legitimate application's code, the attacker will always be able to request tokens from the provider in exactly the same way as the legitimate application code. As a result, not even a completely isolated token storage solution can address the dangers of the second threat, where the attacker requests tokens from the provider.
攻撃者のコードは正規のアプリケーションのコードと区別できなくなるため、攻撃者は常に正規のアプリケーション コードとまったく同じ方法でプロバイダーにトークンを要求できます。その結果、完全に分離されたトークン ストレージ ソリューションでも、攻撃者がプロバイダーにトークンを要求する 2 番目の脅威の危険に対処できません。
That said, the different security properties of browser-based storage solutions will impact the attacker's ability to obtain existing tokens from storage.
ただし、ブラウザベースのストレージ ソリューションのさまざまなセキュリティ特性は、攻撃者がストレージから既存のトークンを取得する能力に影響を与えます。
Browser cookies are both a storage mechanism and a transport mechanism. The browser automatically supports both mechanisms through the corresponding request and response headers, resulting in the storage of cookies in the browser and the automatic inclusion of cookies on outgoing requests provided they match the cookie's domain, path, or other properties.
ブラウザの Cookie は、保存メカニズムと転送メカニズムの両方です。ブラウザーは、対応するリクエスト ヘッダーとレスポンス ヘッダーを通じて両方のメカニズムを自動的にサポートします。その結果、ブラウザーに Cookie が保存され、Cookie のドメイン、パス、またはその他のプロパティと一致する場合には、発信リクエストに Cookie が自動的に組み込まれます。
Next to header-based control over cookies, browsers also offer a JavaScript Cookie API to get and set cookies. This Cookie API is often mistaken as an easy way to store data in the browser. In such a scenario, the JavaScript code stores a token in a cookie with the intent to retrieve the token for later inclusion in the Authorization header of an API call. However, since the cookie is associated with the domain of the browser-based application, the browser will also send the cookie containing the token when making a request to the server running on this domain. One example of such a request is the browser loading the application after a previous visit to the application ((A) in Figure 3).
Cookie に対するヘッダーベースの制御に加えて、ブラウザは Cookie を取得および設定するための JavaScript Cookie API も提供します。この Cookie API は、ブラウザにデータを保存する簡単な方法であると誤解されることがよくあります。このようなシナリオでは、JavaScript コードは、後で API 呼び出しの Authorization ヘッダーに含めるためにトークンを取得することを目的として、トークンを Cookie に保存します。ただし、Cookie はブラウザベースのアプリケーションのドメインに関連付けられているため、ブラウザはこのドメインで実行されているサーバーにリクエストを行うときに、トークンを含む Cookie も送信します。このようなリクエストの一例は、アプリケーションへの前回のアクセス後にブラウザがアプリケーションをロードすることです (図 3 の (A))。
Because of these unintentional side effects of using cookies for JavaScript-based storage, this practice is NOT RECOMMENDED.
JavaScript ベースのストレージに Cookie を使用すると、こうした意図しない副作用が生じるため、この方法は推奨されません。
Note that this practice is different from the use of cookies in a BFF (discussed in Section 6.1.3.2), where the cookie is inaccessible to JavaScript and is intended to be sent to the backend.
この実践は、Cookie が JavaScript にアクセスできず、バックエンドに送信されることを目的とした BFF での Cookie の使用 (セクション 6.1.3.2 で説明) とは異なることに注意してください。
A Service Worker [W3C.service-workers] offers a fully isolated environment to keep track of tokens. These tokens are inaccessible to the client application, effectively protecting them against exfiltration. To guarantee the security of these tokens, the Service Worker cannot share these tokens with the application. Consequently, whenever the application wants to perform an operation with a token, it has to ask the Service Worker to perform this operation and return the result.
Service Worker [W3C.service-workers] は、トークンを追跡するための完全に分離された環境を提供します。これらのトークンはクライアント アプリケーションからアクセスできないため、漏洩から効果的に保護されます。これらのトークンのセキュリティを保証するために、Service Worker はこれらのトークンをアプリケーションと共有できません。したがって、アプリケーションがトークンを使用して操作を実行したい場合は常に、Service Worker にこの操作を実行して結果を返すように要求する必要があります。
When aiming to isolate tokens from the application's execution context, the Service Worker MUST NOT store tokens in any persistent storage API that is shared with the main window. For example, currently, the IndexedDB storage is shared between the browsing context and Service Worker and therefore is not a suitable place for the Service Worker to persist data that should remain inaccessible to the main window. Consequently, the Service Worker currently does not have access to an isolated persistent storage area.
アプリケーションの実行コンテキストからトークンを分離することを目的とする場合、Service Worker はメイン ウィンドウと共有される永続ストレージ API にトークンを保存してはなりません (MUST NOT)。たとえば、現在、IndexedDB ストレージはブラウジング コンテキストと Service Worker の間で共有されているため、Service Worker がメイン ウィンドウからアクセスできないデータを永続化するのに適した場所ではありません。したがって、Service Worker は現在、分離された永続ストレージ領域にアクセスできません。
As discussed before, the use of a Service Worker does not prevent an attacker from obtaining a new set of tokens. Similarly, if the application is responsible for obtaining tokens from the authorization server and passing them to a Service Worker for further management, the attacker can perform the same operation as the legitimate application to obtain these tokens.
前に説明したように、Service Worker を使用しても、攻撃者が新しいトークンのセットを取得することは妨げられません。同様に、アプリケーションが認可サーバーからトークンを取得し、さらなる管理のためにそれらを Service Worker に渡す責任がある場合、攻撃者は正規のアプリケーションと同じ操作を実行してこれらのトークンを取得する可能性があります。
The application can use a Web Worker [WebWorker], which results in an almost identical scenario as the previous one that relies on a Service Worker. The difference between a Service Worker and a Web Worker is the level of access and its runtime properties. Service Workers can intercept and modify outgoing requests, while Web Workers are just a way to run background tasks. Web Workers are ephemeral and disappear when the browsing context is closed, while Service Workers are persistent services registered in the browser.
アプリケーションは Web ワーカー [WebWorker] を使用でき、その結果、Service Worker に依存する前述のシナリオとほぼ同じになります。Service Worker と Web Worker の違いは、アクセスのレベルとその実行時プロパティです。Service Worker は送信リクエストをインターセプトして変更できますが、Web Worker はバックグラウンド タスクを実行するための単なる手段です。Web ワーカーは一時的であり、閲覧コンテキストが閉じられると消えますが、サービス ワーカーはブラウザに登録された永続的なサービスです。
The security properties of using a Web Worker are identical to using Service Workers. When tokens are exposed to the application, they become vulnerable. When tokens need to be used, the operation that relies on them has to be carried out by the Web Worker.
Web Worker を使用する場合のセキュリティ プロパティは、Service Worker を使用する場合と同じです。トークンがアプリケーションに公開されると、脆弱になります。トークンを使用する必要がある場合、トークンに依存する操作は Web ワーカーによって実行される必要があります。
One common method to isolate the refresh token is to use Web Workers. In such a scenario, the application starts an Authorization Code flow from a Web Worker. The authorization code from the redirect is forwarded to the Web Worker, which then exchanges it for tokens. The Web Worker keeps the refresh token in memory and sends the access token to the main application. The main application uses the access token as desired. When the application needs to run a refresh token flow, it asks the Web Worker to do so, after which the application obtains a fresh access token.
リフレッシュ トークンを分離する一般的な方法の 1 つは、Web ワーカーを使用することです。このようなシナリオでは、アプリケーションは Web ワーカーから認証コード フローを開始します。リダイレクトからの認証コードは Web ワーカーに転送され、Web ワーカーはそれをトークンと交換します。Web ワーカーは、リフレッシュ トークンをメモリに保持し、アクセス トークンをメイン アプリケーションに送信します。メイン アプリケーションは必要に応じてアクセス トークンを使用します。アプリケーションはリフレッシュ トークン フローを実行する必要がある場合、Web ワーカーにそうするように要求し、その後アプリケーションは新しいアクセス トークンを取得します。
In this scenario, the application's own refresh token is effectively protected against exfiltration, but the access token is not. Additionally, nothing would prevent an attacker from obtaining their own tokens by running a new Authorization Code flow (Section 5.1.3).
このシナリオでは、アプリケーション自体のリフレッシュ トークンは漏洩から効果的に保護されますが、アクセス トークンは保護されません。さらに、攻撃者が新しい認可コード フロー (セクション 5.1.3) を実行して独自のトークンを取得することを妨げるものはありません。
Another option is keeping tokens in memory without using any persistent storage. Doing so limits the exposure of the tokens to the current execution context only but has the downside of not being able to persist tokens between page loads.
もう 1 つのオプションは、永続ストレージを使用せずにトークンをメモリ内に保持することです。これを行うと、トークンの公開が現在の実行コンテキストのみに制限されますが、ページの読み込み間でトークンを保持できないという欠点があります。
In a JavaScript execution environment, the security of in-memory token storage can be further enhanced by using a closure variable to effectively shield the token from direct access. By using closures, the token is only accessible to the predefined functions inside the closure, such as a function to make a request to the resource server.
JavaScript 実行環境では、クロージャ変数を使用してトークンを直接アクセスから効果的に保護することで、メモリ内トークン ストレージのセキュリティをさらに強化できます。クロージャを使用すると、トークンは、リソース サーバーにリクエストを行う関数など、クロージャ内の事前定義された関数にのみアクセスできます。
While closures work well in simple, isolated environments, they are tricky to secure in a complex environment like the browser's execution environment. For example, a closure relies on a variety of outside functions to execute its operations, such as toString or networking APIs. Using prototype poisoning, an attacker can substitute these functions with malicious versions, causing the closure's future operations to use these malicious versions. Inside the malicious function, the attacker can gain access to the function arguments, which may expose the tokens from within the closure to the attacker.
クロージャは単純な隔離された環境ではうまく機能しますが、ブラウザの実行環境のような複雑な環境ではセキュリティを確保するのが困難です。たとえば、クロージャは、toString やネットワーク API など、さまざまな外部関数に依存して操作を実行します。プロトタイプポイズニングを使用すると、攻撃者はこれらの関数を悪意のあるバージョンに置き換えることができ、クロージャの今後の操作でこれらの悪意のあるバージョンが使用されるようになります。悪意のある関数内で、攻撃者は関数の引数にアクセスできるため、クロージャ内のトークンが攻撃者に公開される可能性があります。
The persistent storage APIs currently available in browsers as of this writing are localStorage [WebStorage], sessionStorage [WebStorage], and IndexedDB [W3C.IndexedDB].
この記事の執筆時点で現在ブラウザで利用できる永続ストレージ API は、localStorage [WebStorage]、sessionStorage [WebStorage]、および IndexedDB [W3C.IndexedDB] です。
localStorage persists between page reloads and is shared across all tabs. This storage is accessible to the entire origin and persists longer term. localStorage does not protect against unauthorized access from malicious JavaScript, as the attacker would be running code within the same origin, and as such, would be able to read the contents of the localStorage. Additionally, localStorage is a synchronous API, blocking other JavaScript until the operation completes.
localStorage はページのリロード間で保持され、すべてのタブで共有されます。このストレージはオリジン全体にアクセスでき、長期間存続します。localStorage は、悪意のある JavaScript からの不正アクセスに対しては保護しません。攻撃者が同じオリジン内でコードを実行し、localStorage の内容を読み取ることができるためです。さらに、localStorage は同期 API であり、操作が完了するまで他の JavaScript をブロックします。
sessionStorage is similar to localStorage, except that the lifetime of sessionStorage is linked to the lifetime of a browser tab. Additionally, sessionStorage is not shared between multiple tabs open to pages on the same origin, which slightly reduces the exposure of the tokens in sessionStorage.
sessionStorage は localStorage に似ていますが、sessionStorage の有効期間がブラウザ タブの有効期間にリンクされている点が異なります。さらに、sessionStorage は、同じオリジン上のページを開いている複数のタブ間で共有されないため、sessionStorage 内のトークンの露出がわずかに減少します。
IndexedDB is a persistent storage mechanism like localStorage, but it is shared between multiple tabs as well as between the browsing context and Service Workers. Additionally, IndexedDB is an asynchronous API, which is preferred over the synchronous localStorage API.
IndexedDB は localStorage のような永続ストレージ メカニズムですが、複数のタブ間、および閲覧コンテキストと Service Worker の間で共有されます。さらに、IndexedDB は非同期 API であり、同期 localStorage API よりも優先されます。
Note that the main difference between these patterns is the exposure of the data, but none of these options can fully mitigate token exfiltration when the attacker can execute malicious code in the application's execution environment.
これらのパターンの主な違いはデータの公開ですが、攻撃者がアプリケーションの実行環境で悪意のあるコードを実行できる場合、これらのオプションのいずれもトークンの漏洩を完全には軽減できないことに注意してください。
In all cases, as of this writing, there is no guarantee that browser storage is encrypted at rest. This behavior potentially exposes tokens to attackers that have the ability to read files on disk. While such attacks rely on capabilities that are well beyond the scope of browser-based applications, this topic highlights an important attack vector against modern applications. More and more malware is specifically created to crawl users' machines and look for browser profiles to obtain high-value tokens and session cookies, resulting in account-takeover attacks.
いずれの場合も、この記事の執筆時点では、ブラウザのストレージが保存時に暗号化されるという保証はありません。この動作により、ディスク上のファイルを読み取る機能を持つトークンが攻撃者に公開される可能性があります。このような攻撃はブラウザベースのアプリケーションの範囲をはるかに超えた機能に依存していますが、このトピックでは、最新のアプリケーションに対する重要な攻撃ベクトルに焦点を当てています。ユーザーのマシンをクロールし、ブラウザ プロファイルを探して高価値のトークンやセッション Cookie を取得することを目的として作成されたマルウェアが増えており、その結果、アカウント乗っ取り攻撃が引き起こされます。
While the browser-based application is incapable of mitigating such attacks, the application can mitigate the consequences of such an attack by ensuring data confidentiality using encryption. The [W3C.WebCryptoAPI] provides a mechanism for JavaScript code to generate a secret key, as well as an option for that key to be non-exportable. A JavaScript application could then use this API to encrypt and decrypt tokens before storing them. However, the [W3C.WebCryptoAPI] specification only ensures that the key is not exportable to the browser code, but it does not place any requirements on the underlying storage of the key itself with the operating system. As such, a non-exportable key cannot be relied on as a way to protect against exfiltration from the underlying filesystem.
ブラウザベースのアプリケーションはそのような攻撃を軽減することはできませんが、アプリケーションは暗号化を使用してデータの機密性を確保することで、そのような攻撃の影響を軽減できます。[W3C.WebCryptoAPI] は、JavaScript コードが秘密鍵を生成するメカニズムと、その鍵をエクスポート不可能にするオプションを提供します。JavaScript アプリケーションは、この API を使用して、トークンを保存する前に暗号化および復号化できます。ただし、[W3C.WebCryptoAPI] 仕様は、キーがブラウザ コードにエクスポートできないことを保証するだけで、オペレーティング システムでのキー自体の基盤となるストレージについてはいかなる要件も課しません。したがって、エクスポート不可能なキーは、基盤となるファイル システムからの漏洩を防ぐ方法として信頼できません。
In order to protect against token exfiltration from the filesystem, the encryption keys would need to be stored somewhere other than the filesystem, such as on a remote server. This introduces new complexity for a purely browser-based app and is out of scope of this document.
ファイルシステムからのトークンの流出を防ぐには、暗号化キーをファイルシステム以外の場所 (リモートサーバーなど) に保存する必要があります。これにより、純粋なブラウザベースのアプリに新たな複雑さが生じるため、このドキュメントの範囲外となります。
A general security best practice in the OAuth world is to minimize the authority associated with access tokens. This best practice is applicable to all the architectures discussed in this specification. Concretely, the following considerations can help minimize the authority of access tokens:
OAuth の世界における一般的なセキュリティのベスト プラクティスは、アクセス トークンに関連付けられた権限を最小限に抑えることです。このベスト プラクティスは、この仕様で説明するすべてのアーキテクチャに適用できます。具体的には、次の考慮事項は、アクセス トークンの権限を最小限に抑えるのに役立ちます。
* Reduce the lifetime of access tokens and rely on refresh tokens for access token renewal
* アクセス トークンの有効期間を短縮し、アクセス トークンの更新にはリフレッシュ トークンを使用します。
* Reduce the scopes or permissions associated with the access tokens
* アクセス トークンに関連付けられたスコープまたは権限を減らす
* Restrict access tokens to a single resource using the extension described in [RFC8707]
* [RFC8707] で説明されている拡張機能を使用して、アクセス トークンを単一のリソースに制限します
When OpenID Connect is used, it is important to avoid sensitive information disclosure through the claims in the ID Token. The authorization server SHOULD NOT include any ID Token claims that aren't used by the client.
OpenID Connect を使用する場合、ID トークン内のクレームを通じて機密情報の開示を避けることが重要です。認可サーバーには、クライアントによって使用されない ID トークン要求を含めるべきではありません (SHOULD NOT)。
As discussed throughout this document, the use of sender-constrained tokens does not solve the security limitations of browser-only OAuth clients. However, when the level of security offered by a token-mediating backend (Section 6.2) or a browser-only OAuth client (Section 6.3) suffices for the use case at hand, sender-constrained tokens can be used to enhance the security of both access tokens and refresh tokens. One method of implementing sender-constrained tokens in a way that is usable from browser-based applications is DPoP [RFC9449].
このドキュメント全体で説明しているように、送信者制限トークンを使用しても、ブラウザー専用 OAuth クライアントのセキュリティ制限は解決されません。ただし、トークン仲介バックエンド (セクション 6.2) またはブラウザ専用 OAuth クライアント (セクション 6.3) によって提供されるセキュリティのレベルが当面のユースケースに十分である場合、送信者制約付きトークンを使用して、アクセス トークンとリフレッシュ トークンの両方のセキュリティを強化できます。ブラウザベースのアプリケーションから使用できる方法で送信者制約トークンを実装する方法の 1 つは、DPoP [RFC9449] です。
When using sender-constrained tokens, the OAuth client has to prove possession of a private key in order to use the token, such that the token isn't usable by itself. If a sender-constrained token is stolen, the attacker wouldn't be able to use the token directly; they would also need to steal the private key. In essence, one could say that using sender-constrained tokens shifts the challenge of securely storing the token to securely storing the private key. Ideally, the application should use a non-exportable private key, such as generating one with the [W3C.WebCryptoAPI]. With an unencrypted token in the browser storage protected by a non-exportable private key, an XSS attack would not be able to extract the key, so the token would not be usable by the attacker.
送信者制限トークンを使用する場合、OAuth クライアントは、トークンを単独で使用できないように、トークンを使用するために秘密キーの所有を証明する必要があります。送信者制限付きトークンが盗まれた場合、攻撃者はそのトークンを直接使用できなくなります。秘密鍵も盗む必要があります。本質的に、送信者制限付きトークンを使用すると、トークンを安全に保存するという課題が、秘密鍵を安全に保存することに移行すると言えます。理想的には、アプリケーションは [W3C.WebCryptoAPI] で生成するなど、エクスポートできない秘密鍵を使用する必要があります。ブラウザ ストレージ内に暗号化されていないトークンがエクスポート不可能な秘密キーで保護されている場合、XSS 攻撃ではキーを抽出できないため、攻撃者はトークンを使用できません。
If the application is unable to use an API that generates a non-exportable key, the application should take measures to isolate the private key from its own execution context. The techniques for doing so are similar to using a secure token storage mechanism, as discussed in Section 8.
アプリケーションがエクスポート不可能なキーを生成する API を使用できない場合、アプリケーションは秘密キーを独自の実行コンテキストから分離する措置を講じる必要があります。これを行うための手法は、セクション 8 で説明したように、安全なトークン ストレージ メカニズムを使用するのと似ています。
While a non-exportable key is protected from exfiltration from within the JavaScript context, the exfiltration of the underlying private key from the filesystem is still a potential attack vector. At the time of writing, there is no guarantee made in [W3C.WebCryptoAPI] that a non-exportable key is actually protected by a Trusted Platform Module (TPM) or stored in an encrypted form on disk. Exfiltration of the non-exportable key from the underlying filesystem may still be possible if the attacker can get access to the filesystem of the user's machine, for example, via malware. This effectively makes the potential attack vector equivalent to a session hijacking attack.
エクスポートできないキーは JavaScript コンテキスト内からの漏洩から保護されていますが、ファイル システムからの基礎となる秘密キーの漏洩は依然として潜在的な攻撃ベクトルです。執筆時点では、[W3C.WebCryptoAPI] では、エクスポート不可能な鍵がトラステッド プラットフォーム モジュール (TPM) によって実際に保護されているか、暗号化された形式でディスクに保存されているかという保証はありません。攻撃者がマルウェアなどを介してユーザーのマシンのファイル システムにアクセスできる場合、基盤となるファイル システムからエクスポート不可能なキーを抽出する可能性は依然としてあります。これにより、潜在的な攻撃ベクトルは事実上、セッション ハイジャック攻撃と同等になります。
Authorization server mix-up attacks mark a severe threat to every client that supports at least two authorization servers. Section 4.4 of [RFC9700] provides additional details about mix-up attacks and the countermeasures mentioned above.
認可サーバーの取り違え攻撃は、少なくとも 2 つの認可サーバーをサポートするすべてのクライアントにとって重大な脅威となります。[RFC9700] のセクション 4.4 には、上記の混合攻撃とその対策に関する追加の詳細が記載されています。
Many of the web's security mechanisms rely on origins, which are defined as the triple <scheme, hostname, port>. For example, browsers automatically isolate browsing contexts with different origins, limit resources to certain origins, and apply CORS restrictions to outgoing cross-origin requests.
Web のセキュリティ メカニズムの多くは、<スキーム、ホスト名、ポート> の 3 要素として定義されるオリジンに依存しています。たとえば、ブラウザーは、異なるオリジンを持つ閲覧コンテキストを自動的に分離し、リソースを特定のオリジンに制限し、発信クロスオリジン要求に CORS 制限を適用します。
Therefore, it is considered a best practice to avoid deploying more than one application in a single origin. An architecture that only deploys a single application in an origin can leverage these browser restrictions to increase the security of the application. Additionally, having a single origin per application makes it easier to configure and deploy security measures such as CORS, CSP, etc.
したがって、単一のオリジンに複数のアプリケーションをデプロイしないことがベスト プラクティスと考えられます。オリジンに単一のアプリケーションのみをデプロイするアーキテクチャでは、これらのブラウザ制限を利用してアプリケーションのセキュリティを強化できます。さらに、アプリケーションごとに単一のオリジンを持つことで、CORS、CSP などのセキュリティ対策の構成と展開が容易になります。
This document has no IANA actions.
この文書には IANA のアクションはありません。
[Fetch] WHATWG, "Fetch", WHATWG Living Standard,
<https://fetch.spec.whatwg.org/>. Commit snapshot:
<https://fetch.spec.whatwg.org/commit-snapshots/
d9c7b6d31067a7eb13110950ef67db54c6362cfa/>.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997,
<https://www.rfc-editor.org/info/rfc2119>.
[RFC6749] Hardt, D., Ed., "The OAuth 2.0 Authorization Framework",
RFC 6749, DOI 10.17487/RFC6749, October 2012,
<https://www.rfc-editor.org/info/rfc6749>.
[RFC6750] Jones, M. and D. Hardt, "The OAuth 2.0 Authorization
Framework: Bearer Token Usage", RFC 6750,
DOI 10.17487/RFC6750, October 2012,
<https://www.rfc-editor.org/info/rfc6750>.
[RFC7636] Sakimura, N., Ed., Bradley, J., and N. Agarwal, "Proof Key
for Code Exchange by OAuth Public Clients", RFC 7636,
DOI 10.17487/RFC7636, September 2015,
<https://www.rfc-editor.org/info/rfc7636>.
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
May 2017, <https://www.rfc-editor.org/info/rfc8174>.
[RFC8252] Denniss, W. and J. Bradley, "OAuth 2.0 for Native Apps",
BCP 212, RFC 8252, DOI 10.17487/RFC8252, October 2017,
<https://www.rfc-editor.org/info/rfc8252>.
[RFC8707] Campbell, B., Bradley, J., and H. Tschofenig, "Resource
Indicators for OAuth 2.0", RFC 8707, DOI 10.17487/RFC8707,
February 2020, <https://www.rfc-editor.org/info/rfc8707>.
[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,
September 2023, <https://www.rfc-editor.org/info/rfc9449>.
[RFC9700] Lodderstedt, T., Bradley, J., Labunets, A., and D. Fett,
"Best Current Practice for OAuth 2.0 Security", BCP 240,
RFC 9700, DOI 10.17487/RFC9700, January 2025,
<https://www.rfc-editor.org/info/rfc9700>.
[W3C.service-workers]
Chintala, M., Ed. and Y. Yanagisawa, Ed., "Service Workers
Nightly", W3C Recommendation, 26 January 2026,
<https://www.w3.org/TR/2026/CRD-service-workers-
20260126/>. Latest version available at
<https://www.w3.org/TR/service-workers/>.
[WebMessaging]
WHATWG, "HTML - Cross-document messaging", WHATWG Living
Standard, <https://html.spec.whatwg.org/#web-messaging>.
Commit snapshot:
<https://html.spec.whatwg.org/commit-snapshots/
b4b94b1db80aa55a143e1f74f6ad9d4a185f2333/#web-messaging>.
[COOKIES] van Kesteren, A. and J. Hofmann, "Cookies: HTTP State
Management Mechanism", Work in Progress, Internet-Draft,
draft-ietf-httpbis-layered-cookies-02, 21 May 2026,
<https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-
layered-cookies-02>.
[CryptoKeyPair]
Mozilla Developer Network, "CryptoKeyPair",
<https://developer.mozilla.org/en-US/docs/Web/API/
CryptoKeyPair>.
[HTML] WHATWG, "HTML", WHATWG Living Standard,
<https://html.spec.whatwg.org/>. Commit snapshot:
<https://html.spec.whatwg.org/commit-snapshots/
b4b94b1db80aa55a143e1f74f6ad9d4a185f2333/>.
[OpenID] Sakimura, N., Bradley, J., Jones, M., de Medeiros, B., and
C. Mortimore, "OpenID Connect Core 1.0 incorporating
errata set 2", 15 December 2023,
<https://openid.net/specs/openid-connect-core-
1_0-errata2.html>.
[OWASPCheatSheet]
"OWASP Cheat Sheet",
<https://cheatsheetseries.owasp.org/>.
[RFC6265bis]
Bingler, S., Ed., West, M., Ed., and J. Wilander, Ed.,
"Cookies: HTTP State Management Mechanism", Work in
Progress, Internet-Draft, draft-ietf-httpbis-rfc6265bis-
22, 1 December 2025,
<https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-
rfc6265bis-22>.
[RFC6819] Lodderstedt, T., Ed., McGloin, M., and P. Hunt, "OAuth 2.0
Threat Model and Security Considerations", RFC 6819,
DOI 10.17487/RFC6819, January 2013,
<https://www.rfc-editor.org/info/rfc6819>.
[SessionFixation]
"Session Fixation", <https://owasp.org/www-
community/attacks/Session_fixation>.
[Site] Mozilla Developer Network, "Site",
<https://developer.mozilla.org/en-US/docs/Glossary/Site>.
[W3C.CSP3] West, M., Ed. and A. Sartori, Ed., "Content Security
Policy Level 3", W3C Working Draft, 11 February 2026,
<https://www.w3.org/TR/2026/WD-CSP3-20260505/>. Latest
version available at <https://www.w3.org/TR/CSP3/>.
[W3C.IndexedDB]
Becker, S., Ed., "Indexed Database API 3.0", W3C Working
Draft, 13 August 2025,
<https://www.w3.org/TR/2025/WD-IndexedDB-3-20250813/>.
Latest version available at
<https://www.w3.org/TR/IndexedDB/>.
[W3C.SRI] Braun, F., Ed., "Subresource Integrity", W3C Working
Draft, 10 July 2025,
<https://www.w3.org/TR/2025/WD-sri-2-20250710/>. Latest
version available at <https://www.w3.org/TR/sri-2/>.
[W3C.wasm-core-2]
Rossberg, A., Ed., "WebAssembly Core Specification", W3C
Candidate Recommendation Draft, 10 February 2026,
<https://www.w3.org/TR/2026/CRD-wasm-core-2-20260210/>.
Latest version available at
<https://www.w3.org/TR/wasm-core-2/>.
[W3C.WebCryptoAPI]
Huigens, D., Ed., "Web Cryptography Level 2", W3C First
Public Working Draft, 22 April 2025,
<https://www.w3.org/TR/2025/WD-webcrypto-2-20250422/>.
Latest version available at
<https://www.w3.org/TR/webcrypto-2/>.
[WebStorage]
WHATWG, "HTML - Web storage", WHATWG Living Standard,
<https://html.spec.whatwg.org/#webstorage>.
<https://html.spec.whatwg.org/commit-snapshots/
b4b94b1db80aa55a143e1f74f6ad9d4a185f2333/#webstorage>.
[WebWorker]
WHATWG, "HTML - Web workers", WHATWG Living Standard,
<https://html.spec.whatwg.org/#workers>. Commit snapshot:
<https://html.spec.whatwg.org/commit-snapshots/
b4b94b1db80aa55a143e1f74f6ad9d4a185f2333/#workers>.
The authors would like to acknowledge the work of William Denniss and John Bradley, whose recommendations for native applications informed many of the best practices for browser-based applications. The authors would also like to thank Hannes Tschofenig and Torsten Lodderstedt, the attendees of the Internet Identity Workshop 27 session at which this BCP was originally proposed, and the following individuals who contributed ideas, feedback, and wording that shaped and formed the final specification:
著者らは、ネイティブ アプリケーションに関する推奨事項によって、ブラウザ ベースのアプリケーションのベスト プラクティスの多くに情報を与えた William Denniss と John Bradley の業績に感謝したいと思います。また、著者らは、この BCP が最初に提案された Internet Identity Workshop 27 セッションの参加者である Hannes Tschofenig 氏と Torsten Lodderstedt 氏、および最終仕様を形作り形成するアイデア、フィードバック、文言に貢献した以下の方々に感謝します。
Andy Barlow, Andy Newton, Annabelle Backman, Brian Campbell, Brock Allen, Christian Mainka, Damien Bowden, Daniel Fett, Deb Cooley, Elar Lang, Emmanuel Gautier, Erik Kline, Éric Vyncke, Eva Sarafianou, Filip Skokan, George Fletcher, Hannes Tschofenig, Janak Amarasena, John Bradley, Joseph Heenan, Justin Richer, Karl McGuinness, Karsten Meyer zu Selhausen, Leo Tohill, Louis Jannett, Marc Blanchet, Martin Thomson, Matthew Bocci, Mike Bishop, Mike Jones, Mohamed Boucadair, Orie Steele, Qin Wu, Rifaat Shekh-Yusef, Roman Danyliw, Sean Kelleher, Thomas Broyer, Thomas Fossati, Tomek Stojecki, Torsten Lodderstedt, Vittorio Bertocci, Watson Ladd, William Duncan, and Yannick Majoros.
アンディ・バーロウ、アンディ・ニュートン、アナベル・バックマン、ブライアン・キャンベル、ブロック・アレン、クリスチャン・メインカ、ダミアン・ボーデン、ダニエル・フェット、デブ・クーリー、エラー・ラング、エマニュエル・ゴーティエ、エリック・クライン、エリック・ヴィンケ、エヴァ・サラフィアノウ、フィリップ・スコカン、ジョージ・フレッチャー、ハンネス・チョフェニグ、ヤナク・アマラセナ、ジョン・ブラッドリー、ジョセフ・ヒーナン、ジャスティンリッチャー、カール・マクギネス、カルステン・マイヤー・ズ・ゼルハウゼン、レオ・トーヒル、ルイ・ジャネット、マーク・ブランシェット、マーティン・トムソン、マシュー・ボッチ、マイク・ビショップ、マイク・ジョーンズ、モハメド・ブーカデア、オリー・スティール、チン・ウー、リファート・シェク=ユセフ、ローマン・ダニリュー、ショーン・ケレハー、トーマス・ブロイヤー、トーマス・フォッサティ、トメックストイェッキ、トルステン・ロダーシュテット、ヴィットリオ・ベルトッチ、ワトソン・ラッド、ウィリアム・ダンカン、ヤニック・マジョロス。
Aaron Parecki
Okta
Email: aaron@parecki.com
URI: https://aaronparecki.com
Philippe De Ryck
Pragmatic Web Security
Email: philippe@pragmaticwebsecurity.com
David Waite
Ping Identity
Email: dwaite@pingidentity.com