Skip to content

Best Current Practice for OAuth 2.0 Security(RFC 9700)

Internet Engineering Task Force (IETF) の BCP 文書であり、OAuth 2.0 の「現時点での最良のセキュリティ実践」をまとめたものです。RFC 6749 / 6750 / 6819 の Threat model とセキュリティ助言を、OAuth 2.0 公開後の実運用で得られた知見や新たな脅威を踏まえて更新・拡張し、より安全性が低い(あるいは危険な)運用モードの一部を非推奨化します。

Abstract(概要)

本書は OAuth 2.0 の best current security practice(現時点での最良のセキュリティ実践)を記述します。OAuth 2.0 公開後に蓄積された実運用上の経験を取り込み、RFC 6749、6750、6819 で示された脅威モデルとセキュリティ助言を更新・拡張します。また、OAuth 2.0 の適用範囲が広がったことにより重要性が増した新しい脅威も対象に含めます。さらに、安全性が低い、または安全でないと判断される一部の運用モードを非推奨とします。

Status of This Memo(この文書の位置づけ)

このメモは Internet Best Current Practice を文書化したものです。

本書は Internet Engineering Task Force (IETF) の成果物であり、IETF コミュニティの合意を反映しています。公開レビューを経て、Internet Engineering Steering Group (IESG) により出版が承認されています。BCP に関する追加情報は RFC 7841 の Section 2 を参照してください。

この文書の現在の状態、正誤表(errata)、およびフィードバック方法は、以下から取得できます。 https://www.rfc-editor.org/info/rfc9700

Copyright (c) 2025 IETF Trust および文書の著者として識別された者。All rights reserved.

本書は、出版日時点で有効な BCP 78 および IETF Trust の「IETF Documents に関する Legal Provisions」 (https://trustee.ietf.org/license-info) の対象です。これらは本書に関する権利と制限を定めていますので、注意深く確認してください。本書から抽出される Code Components には、Trust Legal Provisions の Section 4.e で述べられた Revised BSD License の文言を含める必要があり、また Revised BSD License に記載のとおり無保証で提供されます。

Table of Contents

1. Introduction

[RFC6749] および [RFC6750] の公開以降、OAuth 2.0(本書では単に「OAuth」と呼びます)は市場で急速に普及し、API 保護の標準となり、OpenID Connect [OpenID.Core] を用いたフェデレーテッドログインの基盤にもなりました。OAuth は多様なシナリオやさまざまなデプロイ形態で利用されていますが、次の課題が観測されています。

  • OAuth 実装は、既知の実装上の弱点やアンチパターン(つまり、安全でないと見なされるよく知られたパターン)を通じて攻撃されています。これらの脅威の多くは OAuth 2.0 Threat Model and Security Considerations [RFC6819] で議論されていますが、継続的な悪用が示すとおり、より具体的な推奨事項、実装しやすい緩和策、そしてより強い defense in depth が必要です。

  • OAuth は、当初想定よりも高いセキュリティ要件を持つ環境(例: open banking、eHealth、eGovernment、電子署名)で利用されています。これらのユースケースは、より厳格なガイドラインと追加の保護を求めます。

  • OAuth は当初想定よりもはるかに動的な構成で使われるようになり、セキュリティの観点で新しい課題を生んでいます。これらの課題は [RFC6749]、[RFC6750]、[RFC6819] の元々のスコープを超えています。

当初 OAuth は、client、authorization server、resource server の間に静的な関係があることを前提としていました。各 server の URL はデプロイ時に client が把握しており、それが当事者間の信頼関係のアンカーとなっていました。client が正当な server と通信しているかどうかの検証は、TLS の server authentication([RFC6819] の Section 4.5.4 参照)に基づいていました。

OAuth の採用が進むにつれて、この単純なモデルは崩れ、いくつかのシナリオでは、client 側と、特定デプロイメントの authorization server / resource server 側との関係が動的に確立されるモデルに置き換わりました。これにより、同一の client が異なる provider のサービスへアクセスする(標準 API、たとえば email や OpenID Connect の場合)ことができたり、multi-tenant 環境で特定 tenant の front end として機能したりします。

OAuth 2.0 Dynamic Client Registration Protocol [RFC7591] や OAuth 2.0 Authorization Server Metadata [RFC8414] のような拡張は、こうした動的シナリオでの OAuth 利用を支援するために開発されました。

  • 技術は変化しました。たとえば、browser がリダイレクト時に fragment を扱う方法が変わり、それに伴い implicit grant の基盤となるセキュリティモデルも変化しました。

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

当然ながら、既存のすべてのエコシステムや実装が新しい要件に適合するわけではなく、本書に記載された best practices に従うことで相互運用性が損なわれる可能性があります。それでも、可能になり次第できるだけ早く、実装者が自らの実装とエコシステムをアップグレードすることが RECOMMENDED です。

開発中の OAuth 2.1([OAUTH-V2.1])には、本書のセキュリティ推奨事項が取り込まれる予定です。

1.1. Structure

本書の残りは次のように構成されています。Section 2 は、すべての OAuth 実装者にとって最も重要な best practices を要約します。Section 3 は更新された OAuth attacker model を提示します。Section 4 は、(執筆時点で)現実世界で見られる脅威や実装上の問題を詳細に分析し、潜在的な countermeasures について議論します。

1.2. Conventions and Terminology

本書中のキーワード「MUST」「MUST NOT」「REQUIRED」「SHALL」「SHALL NOT」「SHOULD」「SHOULD NOT」「RECOMMENDED」「NOT RECOMMENDED」「MAY」「OPTIONAL」は、すべて大文字で出現する場合に限り、BCP 14 [RFC2119] [RFC8174] で述べられるとおりに解釈されます。

本仕様は、OAuth 2.0 [RFC6749] により定義された「access token」「authorization endpoint」「authorization grant」「authorization server」「client」「client identifier(client ID)」「protected resource」「refresh token」「resource owner」「resource server」「token endpoint」といった用語を用います。

「open redirector」とは、web server 上の endpoint であり、query parameter から取得した任意の URI へ user の browser を転送するものを指します。

2. Best Practices

本セクションは、執筆時点で best practices と見なされる中核的なセキュリティ機構および対策のセットを記述します。これらの機構・対策の詳細(詳細な attack description を含む)と、より一般的でないオプションに対する要件は Section 4 に示します。

2.1. Protecting Redirect-Based Flows

client の redirection URI を事前登録された URI と比較する際、authorization server は、native app の localhost redirection URI における port number(Section 4.1.3 参照)を除き、厳密な文字列一致(exact string matching)を用いなければなりません。これは Authorization Code や access token の漏えい防止(Section 4.1 参照)に寄与します。また、mix-up attack の検出にも役立つ可能性があります(Section 4.4 参照)。

client と authorization server は、query parameter から取得した任意の URI へ user の browser を転送する URL(open redirectors)を、Section 4.11 で述べるとおり露出してはなりません(MUST NOT)。open redirectors は Authorization Code や access token の持ち出し(exfiltration)を可能にします。

client は Cross-Site Request Forgery (CSRF) を防止しなければなりません(MUST)。ここでの CSRF は、authorization server から発生していない(悪意ある第三者から発生した)redirection endpoint への request を指します(詳細は [RFC6819] の Section 4.4.1.8 を参照)。authorization server が Proof Key for Code Exchange (PKCE) [RFC7636] をサポートしていることを確認した client は、PKCE により提供される CSRF 保護に依存してよい(MAY)とします。OpenID Connect のフローでは nonce parameter が CSRF 保護を提供します。それ以外の場合、user agent に安全にバインドされた one-time use の CSRF token を state parameter に載せて CSRF 保護に用いなければなりません(MUST)(Section 4.7.1 参照)。

OAuth client が複数の authorization server とやり取りできる場合、mix-up attack(Section 4.4 参照)への防御が REQUIRED です。そのために、client は次を行うべきです(SHOULD)。

  • [RFC9207] に従い、countermeasure として iss parameter を使用する、または
  • authorization response に含まれる iss 値(たとえば [OpenID.Core] の ID Token 内の iss claim、または [OpenID.JARM] response の iss)に基づく代替 countermeasure を使用し、その値を [RFC9207] に記載のとおり処理する。

これらの選択肢がない場合、client は代替として、Section 4.4.2 に記載のとおり、authorization endpoint と token endpoint を識別するために issuer ごとに異なる redirection URI を使用してよい(MAY)とします。

user credential を含む可能性のある request をリダイレクトする authorization server は、user credential を誤って転送してしまうことを避けなければなりません(MUST)(詳細は Section 4.12 を参照)。

2.1.1. Authorization Code Grant

client は、Section 4.5 で述べる authorization code injection attack と、Authorization Code の不正使用を、次のいずれかで防止しなければなりません(MUST)。

  • Public client は、この目的のために PKCE [RFC7636] を使用しなければなりません(MUST)(Section 4.5.3.1 の動機付け参照)。
  • Confidential client については、PKCE [RFC7636] の使用が RECOMMENDED です。Section 4.5.3.1 で述べるとおり、Authorization Code の不正使用および注入に対して強力な保護を提供します。また副作用として、Section 4.7.1 で述べる強い attacker が存在する場合でも CSRF を防止します。
  • Section 4.5.3.2 で述べる追加の注意事項を満たす場合、confidential OpenID Connect [OpenID.Core] client は代わりに nonce parameter と、ID Token 内の該当 Claim を使用してよい(MAY)。

いずれの場合でも、PKCE の challenge または OpenID Connect の nonce は transaction-specific であり、その transaction を開始した client と user agent に安全にバインドされていなければなりません(MUST)。authorization server は、PKCE challenge または OpenID Connect nonce に定数値が用いられることを検出し、防止するために合理的な努力を行うことが推奨されます。

注: PKCE は native app を保護する機構として設計されましたが、この助言は web application を含むあらゆる種類の OAuth client に適用されます。

PKCE を使用する場合、client は authorization request 内で PKCE verifier を露出しない PKCE code challenge method を使用するべきです(SHOULD)。そうでない場合、authorization request を読み取れる attacker(Section 3 の Attacker (A4) 参照)が PKCE の保護を破れる可能性があります。現時点では S256 が唯一の該当 method です。

authorization server は PKCE [RFC7636] をサポートしなければなりません(MUST)。

client が authorization request に有効な code_challenge parameter を送信した場合、authorization server は token endpoint における code_verifier の正しい使用を強制しなければなりません(MUST)。

authorization server は、code_verifier parameter を含む token request が、authorization request に code_challenge parameter が存在した場合にのみ受理されるようにし、PKCE downgrade attack を緩和しなければなりません(MUST)(詳細は Section 4.8.2)。

authorization server は PKCE サポートを検出できる手段を提供しなければなりません(MUST)。authorization server が Authorization Server Metadata [RFC8414] に、サポートする PKCE challenge method を含む code_challenge_methods_supported 要素を公開することが RECOMMENDED です(client が PKCE サポートを検出するために利用できます)。authorization server は代わりに、デプロイ固有の方法で PKCE サポートを保証または判定してもよい(MAY)とします。

2.1.2. Implicit Grant

implicit grant(response type token)および、authorization response で authorization server が access token を発行する他の response type は、Section 4.1、4.2、4.3、4.6 で述べるとおり、access token の漏えいと access token replay に脆弱です。

さらに、authorization response で access token が発行される場合、access token を特定の client にバインドする sender-constraining の標準化された方法(Section 2.2 で推奨される)は存在しません。これは、漏えいまたは盗難された access token を attacker が resource endpoint で使用できることを意味します。

これらの問題を避けるため、client は implicit grant(response type token)または authorization response で access token を発行する他の response type を使用すべきではありません(SHOULD NOT)。ただし、authorization response における access token injection が防止され、かつ上記の token 漏えいベクタが緩和されている場合はこの限りではありません。

代わりに client は、Section 2.1.1 で規定された response type code(すなわち authorization code grant type)、または token response で access token を発行する別の response type(例: code id_token response type)を使用するべきです(SHOULD)。これにより、authorization server は replay の試行を検出でき、また access token が URL に露出しないため一般に attack surface を低減します。さらに、authorization server は発行する token を sender-constrain できます(Section 2.2 参照)。

2.2. Token Replay Prevention

2.2.1. Access Tokens

sender-constrained access token は、access token の適用範囲を特定の sender に限定します。この sender は、受信者(例: resource server)側でその token を受理してもらう前提として、ある secret に関する知識を示す義務があります。

Authorization Server および resource server は、盗難・漏えいした access token の不正使用を防ぐため、mutual TLS for OAuth 2.0 [RFC8705] や OAuth 2.0 Demonstrating Proof of Possession (DPoP) [RFC9449](Section 4.10.1 参照)のような、access token を sender-constrain する仕組みを使用するべきです(SHOULD)。

2.2.2. Refresh Tokens

public client の Refresh Token は、Section 4.14 に記載のとおり sender-constrained でなければならない(MUST)、または refresh token rotation を使用しなければなりません(MUST)。[RFC6749] は、confidential client の Refresh Token は、それが発行された client のみが使用できることを既に義務付けています。

2.3. Access Token Privilege Restriction

access token に紐づく privilege は、特定の application またはユースケースに必要な最小限に制限されるべきです(SHOULD)。これは、client が resource owner によって許可された privilege を超過することを防ぎます。また、user が(各種 security policy によって)許可された privilege を超過することも防ぎます。privilege 制限は access token 漏えいの影響を減らす助けにもなります。

特に、access token は特定の resource server に対して audience-restricted であるべきです(SHOULD)。それが難しい場合でも、少数の resource server の集合に制限するべきです(SHOULD)。これを実現するには、authorization server が access token を特定の resource server に紐づけ、各 resource server は各 request について、その request とともに送られた access token が当該 resource server 向けであるかを検証する義務があります。そうでない場合、その resource server は当該 request の処理を拒否しなければなりません(MUST)。[RFC9068] で定義される aud claim を、access token の audience restriction に利用してよい(MAY)とします。client と authorization server は、アクセスしたい resource server を決定するために [RFC6749] と [RFC8707] で規定された parameter scope または resource を利用してよい(MAY)とします。

さらに、access token は resource server 上の特定の resource および action に制限されるべきです(SHOULD)。これを実現するには、authorization server が access token を対象 resource と action に紐づけ、各 resource server は各 request について、その request とともに送られた access token が当該 resource に対する当該 action 向けであるかを検証する義務があります。そうでなければ、resource server は当該 request の処理を拒否しなければなりません。client と authorization server は、これらの resource および/または action を決定するために [RFC6749] の parameter scope と、[RFC9396] の authorization_details を利用してよい(MAY)とします。

2.4. Resource Owner Password Credentials Grant

resource owner password credentials grant [RFC6749] は使用してはなりません(MUST NOT)。この grant type は、resource owner の credential を client に対して安全でない形で露出します。client が善良であっても、この grant を使うと攻撃対象領域が増加します(つまり、credential が authorization server 以外の場所でも漏えいし得る)し、user が authorization server 以外の場所に credential を入力することに慣らされてしまいます。

さらに、resource owner password credentials grant は、二要素認証や、複数ステップの user interaction を必要とする authentication process と連携する設計になっていません。cryptographic credential を用いる認証(例: WebCrypto [W3C.WebCrypto]、WebAuthn [W3C.WebAuthn])は、この grant type では実装が不可能な場合があります。これは、この grant が通常、特定の web origin にバインドされるためです。

2.5. Client Authentication

authorization server は、特定のデプロイメントにおいて client の credential の発行/登録プロセスを確立でき、かつそれらの credential の機密性を確保できるのであれば、client authentication を強制するべきです(SHOULD)。

client authentication には、mutual TLS for OAuth 2.0 [RFC8705] や、[RFC7521] と [RFC7523] に従う署名付き JWT("Private Key JWT")など、非対称暗号を用いることが RECOMMENDED です。後者は [OpenID.Core] で client authentication method private_key_jwt として定義されています。非対称暗号を client authentication に使用する場合、authorization server は機微な対称鍵を保持する必要がなくなり、鍵漏えいに対してより堅牢になります。

2.6. Other Recommendations

OAuth Authorization Server Metadata [RFC8414] の利用は、OAuth デプロイメントのセキュリティ改善に役立ちます。

  • セキュリティ機能やその他の新しい OAuth 機能を、準拠した software library により自動的に有効化できるようにします。
  • misconfiguration の可能性を減らします(例: endpoint URL の誤設定(attacker のものかもしれない)や、セキュリティ機能の誤設定)。
  • 暗号鍵の rotation を容易にし、cryptographic agility を確保する助けになります。

そのため、authorization server が [RFC8414] に従い OAuth Authorization Server Metadata を公開し、client が(利用可能なら)この Authorization Server Metadata を用いて自己設定を行うことが RECOMMENDED です。

Section 4.15.1 に記載された条件下では、authorization server は client が自分の client_id や、真正な resource owner との混同を引き起こしうる他の claim に影響を与えることを許可すべきではありません(SHOULD NOT)。

client と resource server の間では [BCP195] に従う end-to-end TLS を用いることが RECOMMENDED です。もし TLS トラフィックを中継点で終端する必要がある場合は、追加のセキュリティ助言として Section 4.13 を参照してください。

authorization response は暗号化されていないネットワーク接続上で送信されてはなりません(MUST NOT)。このため、authorization server は http scheme を使う redirection URI を許可してはなりません(MUST NOT)。ただし、[RFC8252] の Section 7.3 で述べる loopback interface redirection を利用する native client は例外です。

authorization response が HTTP redirect の代わりに postMessage [WHATWG.postmessage_api] のような in-browser communication 技法で送られる場合、browser 内 message の initiator と receiver の両方が、Section 4.17 に記載のとおり厳格に検証されなければなりません(MUST)。

browser-based client をサポートするために、そのような client が直接アクセスする endpoint(Token Endpoint、Authorization Server Metadata Endpoint、jwks_uri Endpoint、Dynamic Client Registration Endpoint を含む)は Cross-Origin Resource Sharing (CORS) [WHATWG.CORS] の利用をサポートしてよい(MAY)とします。しかし、authorization endpoint では CORS をサポートしてはなりません(MUST NOT)。client はこの endpoint に直接アクセスせず、代わりに user agent をそこへ redirect するからです。

3. The Updated OAuth 2.0 Attacker Model

[RFC6819] では、OAuth デプロイメントが防御しなければならない脅威を記述する Threat model が提示されています。その過程で [RFC6819] は、attacker とその能力について一定の前提を置いており、暗黙に attacker model を確立しています。以下では、この attacker model を明示し、(Section 1 で述べた)複数当事者が関与する潜在的に動的な関係性を考慮して更新・拡張し、新しいタイプの attacker を含め、attacker model をより明確に定義します。

本書の目的は、authorization server における resource owner(user agent を伴う)の authorization と、その後の resource server における access token の利用が、実用上可能な限り、少なくとも以下の attacker に対して保護されることを確実にすることです。

(A1) 「honest」なもの以外も含め、browser や server を含む任意個の network endpoint を用意し運用できる Web attacker。Web attacker は resource owner が訪問する website を用意でき、自身の user agent を運用でき、protocol に参加できます。

特に、Web attacker は authorization server に登録された OAuth client を運用でき、また resource owner や他の resource owner が(「honest」なものと並行して)利用できる独自の authorization server / resource server を運用できます。

また、Web attacker は resource owner を任意の attacker 選択 URI にいつでも browser で移動させられると仮定しなければなりません。実際には、たとえば広告ネットワークへの悪意ある広告の注入や、正規に見える email の送信など、多くの方法で達成できます。

Web attacker は自分自身の user credential を用いて新しい message を作成でき、また過去に学習した secret を使うこともできます。たとえば Web attacker が、誤設定された redirection URI により user の Authorization Code を学習した場合、その code を access token と交換しようと試みられます。

ただし、Web attacker は、自分に向けられていない message(例: attacker が制御していない authorization server の URL に送られたもの)を読み取ったり改変したりはできません。

(A2) (A1) に加えて、protocol participant が通信する network を完全に制御できる Network attacker。これらは、適切に暗号学的手法(例: TLS)で保護されていない限り、message の盗聴・改ざん・なりすましが可能です。Network attacker は任意の message をブロックすることもできます。

Web attacker の例としては ISP の顧客が挙げられる一方、Network attacker は ISP 自身、ARP spoofing を用いる公共 Wi-Fi の attacker、あるいはインターネット交換点にアクセスできる国家支援 attacker などが該当し得ます。

上記 (A1) と (A2) は、OAuth に対する形式解析 [arXiv.1601.01229] で用いられた attacker model に準拠します。これは最小の attacker model です。実装者は、自身の OAuth 実装環境におけるあらゆる attacker タイプを考慮しなければなりません(MUST)。たとえば [arXiv.1901.11520] では token endpoint を完全に制御する attacker を含む非常に強い attacker model が使われています。これは、エコシステムにおける endpoint の誤設定の影響をモデル化するもので、Section 2.6 のとおり authorization server metadata を使うことで回避できます。そのため、この attacker はここでは列挙しません。

しかし、OAuth に対する過去の攻撃から、特に以下の attacker タイプが重要であることが示されています。

(A3) authorization response の内容を読み取れるが改変できない attacker(つまり authorization response が attacker に漏えいし得る)。

例として、open redirector attack や mix-up attack(Section 4.4 参照)があり、client が騙されて attacker 制御の authorization server に credential を送る状況が該当します。

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

  • redirect URI の不十分な検証(Section 4.1 参照)
  • mobile OS 上の問題(異なる app が同じ URI を登録できる)
  • browser(history)、proxy server、OS に保存/ログされた URL

(A4) authorization request の内容を読み取れるが改変できない attacker(つまり authorization request が、上記と同様のやり方で attacker に漏えいし得る)。

(A5) authorization server が発行した access token を入手できる attacker。たとえば resource server が侵害された場合、誤設定により access token が attacker 制御の resource server に送られた場合、または social engineering により resource owner に attacker 制御 resource server を使わせた場合などです。Section 4.9.2 も参照してください。

(A3)、(A4)、(A5) は通常 (A1) または (A2) と組み合わさって発生します。attacker は共通の目的のために協力し得ます。

Attacker (A1) または (A2) は resource owner であり得る、あるいは resource owner として振る舞うことができる点に注意してください。たとえば、その attacker は自身の browser を使って、上記の攻撃のいずれかで得た token や Authorization Code を client や resource server に対して replay できます。

本書は (A1) から (A5) の attacker に起因する脅威に焦点を当てます。

4. Attacks and Mitigations

本セクションでは、OAuth 実装に対する attack を詳細に記述し、潜在的な countermeasures も併せて示します。[RFC6819] ですでに扱われている attack と mitigation は、ここでは新しい推奨事項がある場合を除き、列挙しません。

また本セクションは、特定のケースや protocol option に対して、Section 2 を超える追加要件も定義します。

4.1. Insufficient Redirection URI Validation

一部の authorization server は、完全な redirection URI ではなく redirection URI pattern の登録を client に許可しています。その場合、authorization server は実行時に、authorization endpoint に渡された redirection URI parameter の値を、登録済み pattern と照合します。この方式により client は transaction state を追加の redirect URI parameter にエンコードできたり、複数の redirection URI に対して単一の pattern を登録できたりします。

しかしこの方式は、厳密な redirection URI matching よりも実装が複雑で管理上もエラーを招きやすいことが判明しました。pattern-matching 実装や具体的な設定上の欠陥を突く成功例が現実に多数観測されています(例: [research.rub2])。redirection URI の検証が不十分だと、client の識別または authentication(grant と client type に依存)が事実上破綻し、attacker は Authorization Code または access token を取得できてしまいます。方法としては次のいずれかです。

  • user agent を attacker 制御下の URI へ直接送る、または
  • client 側の open redirector と、user agent が URL fragment を扱う仕組みを組み合わせて OAuth credential を attacker に露出させる。

これらの attack は以下の subsections で詳細に示します。

4.1.1. Redirect URI Validation Attacks on Authorization Code Grant

grant_type code を使用する client に対する attack は、次のように成立し得ます。

client ID s6BhdRkqt3 に対して redirection URL pattern https://*.somesite.example/* が登録されていると仮定します。意図としては、たとえば https://app1.somesite.example/redirect のように、somesite.example の任意 subdomain を client の有効な redirection URI にすることです。しかし authorization server の素朴な実装が wildcard * を「任意の文字」と解釈し、「domain name として有効な任意の文字」と解釈しない場合があります。その結果 authorization server は、https://attacker.example/.somesite.example を redirection URI として許可してしまう可能性があります。これは別 domain であり、悪意ある party により制御され得ます。

この場合、attack は次のように実行されます。

まず attacker は、user を改ざんされた URL を開くように誘導し、attacker が制御する page(例: https://www.evil.example)を browser で開かせます(Section 3 の attacker A1 参照)。

この URL は、正当な client の client ID を使って、authorization endpoint に対して次の authorization request を開始します(表示のために改行しています)。

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

authorization server は redirection URI を検証し、client s6BhdRkqt3 の登録済み redirection URL pattern と比較します。authorization request は処理され、user に提示されます。

user が redirection URI を見ない、または attack に気づかない場合、Authorization Code が発行され、即座に attacker の domain に送られます。authorization の自動承認が有効になっている場合([RFC6749] によれば Public client では推奨されませんが)、user の操作なしでも attack は成立します。

attacker が Public client をなりすます場合、attacker は token endpoint で code を token と交換できます。

この attack は confidential client には簡単には成立しません。code exchange には正当 client の secret による authentication が必要なためです。しかし attacker は、Section 4.5 で述べる authorization code injection attack を行うことで、正当な confidential client に code を redeem させることができます。

重要なのは、wildcard を正しく扱う authorization server であっても redirection URI validation の脆弱性があり得る点です。たとえば client が https://*.somesite.example/* を登録し、authorization server が「somesite.example 配下の任意 host を許可する」と解釈するとします。このとき attacker が somesite.example 内に host または subdomain を確保できてしまうと、attacker は正当 client を impersonate できます。

例として、subdomain takeover attack [research.udel] が挙げられます。古い CNAME(例: external-service.somesite.example)が、もはや存在しない外部 DNS 名(例: customer-abc.service.example)を指している場合、attacker が外部サービスに customer-abc として登録することで takeover できる可能性があります。

4.1.2. Redirect URI Validation Attacks on Implicit Grant

上記の attack は implicit grant に対しても同様に成立します。attacker が authorization response を attacker 制御 URI に送れるなら、access token を運ぶ fragment を attacker が直接取得できます。

加えて implicit grant(および [OAuth.Responses] で定義される response_mode=fragment を使う他の grant)では、別種の attack にもさらされ得ます。この attack は、Location header が fragment を含まない redirect の場合、user agent が redirect 先 URL に fragment を再付与するという事実を利用します([RFC9110] の Section 17.11)。ここで述べる attack は、この挙動と「client が open redirector である」状態(Section 4.11.1)を組み合わせて access token を奪取します。これは非常に狭い redirection URI pattern でも回避できる可能性がありますが、厳密な URL matching では回避できません。

client s6BhdRkqt3 の登録済み URL pattern が https://client.somesite.example/cb?*(つまり https://client.somesite.example/cb への redirect であれば任意 parameter を許可)だと仮定します。さらに不運にも client は open redirector を露出しています。この endpoint は redirect_to parameter を受け取り、その target URL に対して HTTP Location header で 303 redirect を返します。

attack は次のように行われます。

最初に attacker は、上と同様に user を騙して https://www.evil.example のような attacker 制御 page を開かせます。

その後 website は、code flow に対する attack とよく似た authorization request を開始しますが、異なる点として open redirector を利用します。redirection URI の parameter に redirect_to=https://attacker.example をエンコードし、response type token を使用します(表示のために改行しています)。

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

redirection URI が登録済み pattern に一致するため、authorization server は request を許可し、結果の access token を 303 redirect で返します(可読性のため一部 parameter を省略)。

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

client.somesite.example では request が open redirector に到達します。endpoint は redirect parameter を読み取り、URL https://attacker.example/ へ HTTP 303 redirect を返します。

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

client.somesite.example の redirector は Location header に fragment を含めないため、user agent は元の fragment #access_token=2YotnFZFEjr1zCsicMWpAA&... を URL に再付与し、次の URL へ移動します。

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

その結果、attacker の page(attacker.example)は fragment にアクセスして access token を取得できます。

4.1.3. Countermeasures

pattern matching を正しく実装・管理する複雑さがセキュリティ問題を引き起こすことは明らかです。そこで本書は、厳密な redirection URI matching を使い、必要なロジックと設定を簡素化するよう助言します。つまり authorization server は、2 つの URI が等しいことを保証しなければなりません(MUST)。詳細は [RFC3986] の Section 6.2.1(Simple String Comparison)を参照してください。唯一の例外は localhost URI を使う native app で、この場合 authorization server は [RFC8252] の Section 7.3 に記載のとおり、可変 port number を許可しなければなりません(MUST)。

追加の推奨事項:

  • redirection URI をホストする web server は open redirector を露出してはなりません(MUST NOT)(Section 4.11 参照)。
  • browser は、Location header の URL にすでに fragment が含まれていない場合に限り、URL fragment を Location redirect URL に再付与します。したがって server は、Location header の URL に任意の fragment identifier(例: #_)を付けることで、browser が fragment を再付与するのを防いでよい(MAY)とします。
  • client は、authorization endpoint で access token を発行させる response type ではなく、authorization code response type を使うべきです(SHOULD)。これにより、authorization server との exchange プロセスにより漏えい credential の再利用に対する countermeasure を提供し、さらに access token の sender-constraining を通じて token replay への countermeasure も提供します。

authorization request(redirection URI を含む)の origin と integrity を検証できる場合、たとえば client authentication を伴う [RFC9101] または [RFC9126] を使うときには、authorization server は追加チェックなしに redirection URI を信頼してよい(MAY)とします。

4.2. Credential Leakage via Referer Headers

authorization request URI または authorization response URI の内容は、Referer HTTP header([RFC9110] の Section 10.1.3)を通じて、意図せず attacker に開示される場合があります。これは、それぞれ authorization server 側の website、または client 側の website から漏えいし得ます。特に重要なのは、Authorization Code や state 値がこの方法で漏えいし得る点です。[RFC9110] の Section 10.1.3 では別の挙動が規定されていますが、browser 実装上の問題により、URI fragment で渡される access token にも同様のことが起こり得ます。Chromium project の(現在は修正済みの)issue [bug.chromium] で示されています。

4.2.1. Leakage from the OAuth Client

OAuth client からの漏えいには、成功した authorization request の結果として client が表示する page が次のいずれかであることが必要です。

  • attacker 制御下の他 page への link を含み、user がその link をクリックする、または
  • third-party content(iframe 内の広告、image など)を含む。たとえば page に user-generated content(blog)が含まれる場合などです。

browser が attacker の page へ移動する、または third-party content を読み込むと、attacker は authorization response URL を受け取り、そこから code や state(および潜在的に access_token)を抽出できます。

4.2.2. Leakage from the Authorization Server

同様に、authorization server の authorization endpoint が上記のような link や third-party content を含む場合、attacker は authorization request から state を学習できる可能性があります。

4.2.3. Consequences

Referer header により有効な code または access token を学習した attacker は、Section 4.1.1、4.5、4.6 で述べる attack を実行できます。attacker が state を学習した場合、state による CSRF 保護は失われ、[RFC6819] の Section 4.4.1.8 で述べる CSRF attack が成立します。

4.2.4. Countermeasures

OAuth authorization response の結果として表示される page と、authorization server の authorization endpoint は、third-party resource や外部 site への link を含めるべきではありません(SHOULD NOT)。

以下の対策により、attack が成功する可能性をさらに下げられます。

  • 適切な Referrer Policy [W3C.webappsec-referrer-policy] を document に適用して Referer header を抑止します("referrer" meta attribute の一部として、または Referrer-Policy header を設定して)。たとえば response header Referrer-Policy: no-referrer は、生成された document から発生するすべての request において Referer header を完全に抑止します。
  • authorization endpoint から access token を発行する response type ではなく、authorization code を使用します。
  • Authorization Code を confidential client または PKCE challenge にバインドします。この場合 attacker は secret を持たないため code exchange を要求できません。
  • [RFC6749] の Section 4.1.2 で述べるとおり、Authorization Code は token endpoint での最初の使用後に authorization server により無効化されなければなりません(MUST)。たとえば正当 client が redeem した後に code が無効化されていれば、attacker が後からその code を exchange しようとしても失敗します。

4.2.4. Countermeasures (continued)

  • ただし、attacker が正当 client より先に code を token に交換できた場合、この対策は attack を緩和できません。そのため [RFC6749] はさらに、code を二度 redeem しようとする試みがあった場合、authorization server はその code に基づいて以前に発行されたすべての token を revoke するべきだと推奨しています(SHOULD)。

  • state 値は、redirection endpoint で最初に使用した後に client により無効化されるべきです(SHOULD)。これを実装しておけば、client の website から Referer header 経由で token を受け取った attacker は、すでに使用済みで client により無効化された state を再利用できません。(ただし、state が authorization server の website から漏えいした場合には有効ではありません。なぜならその時点では state はまだ client の redirection endpoint で使用されていないためです。)

  • authorization response の redirect の代わりに form post response mode を使用します([OAuth.Post] 参照)。

4.3. Credential Leakage via Browser History

Authorization Code と access token は、browser の訪問 URL history に残る可能性があり、それにより以下で述べる attack が成立します。

4.3.1. Authorization Code in Browser History

browser が、provider の authorization endpoint からの redirect の結果として client.example/redirection_endpoint?code=abcd に移動した場合、Authorization Code を含む URL が browser history に残る可能性があります。device にアクセスできる attacker は、その code を入手して replay を試みられます。

Countermeasures:

  • [RFC6819] の Section 4.4.1.1 と Section 4.5 に記載された Authorization Code replay prevention を適用します。
  • authorization response の redirect の代わりに form post response mode を使用します([OAuth.Post] 参照)。

4.3.2. Access Token in Browser History

client または、すでに token を保持している website が、意図的に provider.com/get_user_profile?access_token=abcdef のような page へ移動すると、access token が browser history に残る可能性があります。[RFC6750] はこの実践を推奨せず、token は header で送るよう助言していますが、実際には多くの website が query parameter で access token を渡しています。

implicit grant の場合、provider の authorization endpoint からの redirect により、client.example/redirection_endpoint#access_token=abcdef のような URL が browser history に残ることもあり得ます。

Countermeasures:

  • client は、[RFC6750] の Section 2.3 で述べる方法で、URI query parameter に access token を渡してはなりません(MUST NOT)。この目的には authorization code grant、または form post response mode [OAuth.Post] のような代替の OAuth response mode を利用できます。

4.4. Mix-Up Attacks

Mix-up attack は、OAuth client が 2 つ以上の authorization server とやり取りし、かつ少なくとも 1 つの authorization server が attacker により制御されている scenario で発生し得ます。たとえば attacker が dynamic registration を使って自分の authorization server に client を登録する場合や、authorization server が侵害される場合などです。

この attack の目標は、侵害されていない authorization server の Authorization Code または access token を取得することです。これは、client を騙して、これらの credential を侵害された authorization server(attacker)へ送らせ、侵害されていない authorization/resource server の endpoint で使わせないようにすることで達成されます。

4.4.1. Attack Description

ここでの記述は [arXiv.1601.01229] に従い、いくつかの variant を後述します。

Preconditions: この variant が成立するために、以下を仮定します。

  • implicit または authorization code grant を、複数の authorization server で使用している。そのうち 1 つは「honest」(H-AS) とされ、もう 1 つは attacker が運用する (A-AS) である。
  • client は user により選択された authorization server を、user の browser にバインドされた session に格納し、各 authorization server に対して同じ redirection URI を使用する。

以下では、client が H-AS(URI: https://honest.as.example、client ID: 7ZGZldHQ)および A-AS(URI: https://attacker.example、client ID: 666RVZJTA)に登録されていると仮定します。例示の URL は、表示のため attack に関係する parameter のみに短縮しています。

authorization code grant に対する attack:

  1. user は A-AS を使って grant を開始するよう選択します(例: client の website 上の button をクリック)。
  2. client は user が "A-AS" を選んだことを session に保存し、A-AS の authorization endpoint に Location header を含む redirect を返します。URL は次のとおりです。\ https://attacker.example/authorize?response_type=code&client_id=666RVZJTA
  3. user の browser が attacker の authorization endpoint に移動すると、attacker は直ちに browser を H-AS の authorization endpoint に redirect します。authorization request 内で、attacker は A-AS における client の client ID を H-AS の client ID に置き換えます。したがって browser は、次の Location header を持つ redirect(303 See Other)を受け取ります。\ https://honest.as.example/authorize?response_type=code&client_id=7ZGZldHQ
  4. user は H-AS において client が resource にアクセスすることを authorize します。(この時点で注意深い user は、本来 A-AS を使うつもりが H-AS になっていることに気づくかもしれません。最初に挙げた別 variant ではこの制約はありません。)H-AS は code を発行し、(browser 経由で)client に送り返します。
  5. client は code が A-AS から発行されたものだと誤って仮定したままなので、A-AS の token endpoint で code を redeem しようとします。
  6. 結果として attacker は code を得て、(Public client なら)access token に交換できるか、または Section 4.5 で述べる authorization code injection attack を実行できます。

Variants:

  • Mix-Up with Interception: この variant は、attacker が user の browser から client への最初の request/response pair(user が authorization server を選択し、client により redirect される部分)を intercept し改変できる場合にのみ成立します(Section 3 の Attacker (A2))。これは、user と client の接続に対する attacker-in-the-middle attack により可能になり得ます。この攻撃では user は H-AS を選んで flow を開始しますが、attacker がその request を intercept して user の選択を A-AS に書き換えます。以降は上の Step 2 と同様に進みます。
  • Implicit Grant: implicit grant では Step 4 で code の代わりに access token を attacker が受け取ります。client は flow を A-AS で完了したと信じているため、A-AS userinfo endpoint([OpenID.Core] で定義)への request、または attacker の resource server への request を行い、そこで attacker の authorization server が access token を受け取ります。
  • Per-AS Redirect URIs: client が authorization server ごとに異なる redirection URI を使用し、client が user の session に選択された authorization server を保存せず、authorization server が redirection URI を適切に検査しない場合、attacker は "Cross Social-Network Request Forgery" と呼ばれる attack を実行できます。これらは実際に観測されています。詳細は [research.jcs_14] を参照してください。
  • OpenID Connect: OpenID Connect に対してもいくつかの variant が可能です。これらの attack では attacker は OpenID Connect Discovery [OpenID.Discovery] の機能を悪用したり、access token や ID Token を replay して mix-up attack を行います。詳細は [arXiv.1704.08539] Appendix A および [arXiv.1508.04324v2] の Section 6("Malicious Endpoints Attacks")を参照してください。

4.4.2. Countermeasures (continued)

両方の defense において、client は各 authorization request ごとに、authorization request を送った先の issuer を保存し、その情報を user agent にバインドしなければなりません(MUST)。issuer は、関連する metadata を通じて、当該 flow で使用される authorization endpoint と token endpoint の組を抽象的に識別するものとして機能します。issuer identifier が利用できない場合(たとえば OAuth Authorization Server Metadata [RFC8414] も OpenID Connect Discovery [OpenID.Discovery] も使わない場合)には、この tuple に対する別の一意 identifier、または tuple 自体を利用できます。簡潔化のため、以下ではこのようなデプロイメント固有の identifier も issuer(または issuer identifier)として扱います。

単に authorization server の URL を保存するだけでは mix-up attack の識別に十分ではない点が重要です。attacker は、侵害されていない authorization server の authorization endpoint URL を「自分の」authorization server URL として宣言しつつ、token endpoint を attacker 制御下のものとして宣言できるかもしれません。

4.4.2.1. Mix-Up Defense via Issuer Identification

この defense は、authorization server が authorization response で issuer identifier を client に送ることを必要とします。authorization response を受け取った client は、受信した issuer identifier を保存済み issuer identifier と比較しなければなりません(MUST)。不一致があれば、client は interaction を中止しなければなりません(MUST)。

issuer identifier を client に運ぶ方法はいくつかあります。

  • issuer 情報を、たとえば [RFC9207] で定義される response parameter iss で運べます。
  • OpenID Connect を用い、authorization response に ID Token が返る場合、client は ID Token の iss claim を評価できます。

いずれの場合でも、iss 値は [RFC9207] に従って評価されなければなりません(MUST)。

この defense は issuer 情報を運ぶために新しい OAuth 機能の導入が必要になる場合がありますが、mix-up に対する堅牢で比較的単純な defense です。

4.4.2.2. Mix-Up Defense via Distinct Redirect URIs

この defense では、client は自分がやり取りする issuer ごとに異なる redirection URI を使用しなければなりません(MUST)。

client は、受け取った authorization response が正しい issuer からのものであることを確認するため、当該 issuer 用の distinct redirection URI と、authorization response を受け取った先の URI を比較しなければなりません(MUST)。不一致であれば、client は flow を中止しなければなりません(MUST)。

この defense は既存の OAuth 機能に基づきますが、(いくつかの open banking scheme のように)多くの issuer の利用のために client が一度だけ登録する scenario では使えません。また client registration と密接に結びつくため、自動導入が難しいです。

さらに、attacker はこの defense が提供する保護を迂回できる可能性があります。attacker は「honest」authorization server に対し、client が attacker の authorization server に割り当てた redirect URI を用いて新たな client を登録できるかもしれません。その後、attacker は上記の attack を実行し、client ID を自分が作成した新 client の client ID に置き換えられます。

そのため、この defense は他の option が利用できない場合にのみ使用するべきです(SHOULD)。

4.5. Authorization Code Injection

authorization response に含まれる Authorization Code へアクセスできた attacker(Section 3 の Attacker (A3) 参照)は、その Authorization Code を access token と交換しようとするか、あるいは別の方法で Authorization Code を悪用しようとします。

Authorization Code が Public client 向けに作られた場合、attacker は authorization server の token endpoint に Authorization Code を送り access token を得られます。この attack は [RFC6819] の Section 4.4.1.1 で述べられています。

confidential client の場合、または特定の状況では、attacker は以下で述べる authorization code injection attack を実行できます。

authorization code injection attack では、attacker は盗まれた Authorization Code を、自分自身の client における session に注入しようとします。目的は、client 上での attacker の session を victim の resource または identity に関連づけ、attacker に少なくとも限定的な victim resource への access を与えることです。

この attack の用途は、confidential client の client authentication を迂回すること以外にもあります。

  • attacker が特定 client の特定機能にアクセスしたい場合。例: attacker が特定の app や website で victim を impersonate したい。
  • authorization server または resource server が特定 network に制限されており、attacker が直接アクセスできない場合。

これらの特別なケースを除き、Public client 向けに作られた code に対して authorization code injection は通常あまり魅力的ではありません。なぜなら token endpoint に code を送るほうがより単純で強力な attack だからです(上記参照)。

4.5.1. Attack Description

authorization code injection attack は次のように成立します。

  1. attacker は Authorization Code を入手します(Section 3 の Attacker (A3) 参照)。attack の残りは Web attacker (A1) の能力だけで実行可能です。
  2. attacker は自分の device から、正当な client に対して通常の OAuth authorization process を開始します。
  3. authorization server から正当 client への response において、attacker は新しく作られた Authorization Code を、盗んだ Authorization Code に置き換えます。この response は attacker の device を通過するので、authorization response を intercept して改変できる任意の tool を使えます。network を制御する必要はありません。
  4. 正当 client は、code を authorization server の token endpoint に送り、redirect_uri と client の client ID、および client secret(または他の client authentication 手段)も併せて送ります。
  5. authorization server は client secret を検証し、code が当該 client に発行されたものか、そして実際の redirection URI が redirect_uri parameter と一致するかを検証します([RFC6749] 参照)。
  6. すべての check が成功し、authorization server は access token と他の token を client に発行します。これにより attacker は、正当 client での自分の session を victim の resource および/または identity に関連づけることに成功します。

4.5.2. Discussion

明らかに、Step 5 の check は、code が別の client ID(例: attacker が用意した client)に発行されたものであれば失敗します。また、その Authorization Code が正当 user によってすでに redeem 済みで one-time use であれば、この check も失敗します。

改ざんされた redirection URI によって取得された code を inject しようとする試みも、authorization server が authorization request で使用された完全な redirection URI を保存し、それを redirect_uri parameter と比較するなら検出されるはずです。

[RFC6749] の Section 4.1.3 は authorization server に次を要求しています。

ensure that the "redirect_uri" parameter is present if the
"redirect_uri" parameter was included in the initial authorization
request as described in Section 4.1.1, and if included ensure that
their values are identical.

Section 4.5.1 の attack scenario では、正当 client は常に使用している正しい redirection URI を authorization request に使います。しかしそれは attacker が使った改ざん redirection URI と一致しません(そうでなければ redirect は attacker の page に着地しません)。したがって authorization server は attack を検出して code を exchange しないはずです。

この check は、一定条件が満たされる場合には、別 device 上の同一 client instance から取得された Authorization Code を inject する試みも検出できる可能性があります。

  • redirection URI 自体が nonce または他の one-time use な secret data を含む
  • client がこの data を当該 client instance にバインドしている

しかしこの approach は、authorization endpoint における厳密な redirect URI matching を強制する考え方と衝突します。さらに、provider が token endpoint 段階での redirect_uri check 要件をしばしば無視していることが観測されています。仕様を読むとこの check がセキュリティ上 critical に見えないためかもしれません。

他の provider は redirect_uri parameter を登録済み redirection URI pattern と pattern match するだけです。これにより authorization server は、各 transaction ごとに実際の redirect URI と Authorization Code の結びつきを保存しなくて済みます。しかしこの種の check は仕様の意図を満たしません。改ざん redirection URI が考慮されないため、正当 client の client_id を用いて得られた code や、別 device 上の正当 client を利用して得られた code を inject しても、当該デプロイメントでは検出されません。

また [RFC6749] の Section 4.1.3 の要件は、token endpoint 呼び出しのために client が正しい redirection URI を保存または再構築する必要があり、client 実装の複雑さを増すと考えられています。

client authentication の非対称手段はこの attack を止めません。token endpoint で正当 client が authentication するからです。

そのため本書は代わりに、次で述べる mechanism のいずれかを用いて、特定 transaction の文脈で、特定 device(または特定 user agent)上の特定 client instance に各 Authorization Code をバインドすることを推奨します。

4.5.3. Countermeasures

Authorization Code を client instance にバインドするための良い技術的解決策が 2 つあります。

4.5.3.1. PKCE

[RFC7636] で規定された PKCE mechanism は countermeasure として使用できます(元々は Native App の保護のために設計されましたが)。attacker が Authorization Code を inject しようとすると、code_verifier の check が失敗します。client は自分の正しい verifier を使いますが、code はその verifier と一致しない code_challenge に紐づけられているからです。

PKCE は authorization code injection attack に対して保護するだけでなく、Public client 向けに作られた Authorization Code も保護します。PKCE は、attacker が code_verifier を知らずに、盗んだ Authorization Code を authorization server の token endpoint で redeem できないことを保証します。

4.5.3.2. Nonce

OpenID Connect の既存の nonce parameter は、authorization code injection attack を防げます。nonce 値は one-time use で client により作成されます。client はそれを user agent session にバインドし、OpenID Provider (OP) への初回 request に含めることが期待されています。OP は受け取った nonce 値を、token endpoint での code exchange の一部として発行する ID Token に入れます。attacker が authorization response で Authorization Code を inject すると、client session 内の nonce 値と、token endpoint から受け取った ID Token 内の nonce 値が一致せず、attack が検出されます。ここでの前提は、attacker が(当該 Authorization Code を盗んだ)victim device 上の user agent state を入手できないということです。

重要なのは、この countermeasure が、client が token endpoint から得た ID Token の nonce parameter を適切に check し、その check が成功するまで発行された token を一切使用しない場合にのみ有効だという点です。より正確には、nonce parameter により code injection から自衛する client は次を満たさなければなりません(MUST)。

  1. authorization response で別の ID Token を得ていたとしても(例: response_type=code+id_token)、token endpoint で得た ID Token の nonce を検証すること。
  2. その check が成功するまでは、すべての token(ID Tokens と access token)を無視し、他の目的で使用しないこと。

nonce は Public client の Authorization Code を保護しない点にも注意が必要です。attacker は authorization code injection attack を実行する必要がありません。代わりに、盗んだ Authorization Code を token endpoint に直接送れるからです。

4.5.3.3. Other Solutions

state を code にバインドする、暗号的手段で code を sender-constrain する、per-instance client credential を用いる、といった他の解決策も考えられますが、サポートが不足しており、新たなセキュリティ要件も持ち込みます。

PKCE は OAuth client にとって最も明白な解決策です(執筆時点で利用可能であるため)。nonce は OpenID Connect client に適しています。

4.5.4. Limitations

attacker が victim の authorization request で用いられる nonce または code_challenge の値を改変できる場合、上記 countermeasure を回避できます。attacker は、これらの値を、自分の session で client が選んだものと同じに改変できます(このためには、victim の client session が attacker の session 開始後に始まる必要があります)。その後 attacker が victim から Authorization Code を capture できれば、PKCE や nonce が使われていても、Step 3 で盗んだ code を inject できてしまいます。

この attack は複雑で、attacker と victim の session の密接な相互作用を必要とします。それでもなお、Sections 4.1、4.2、4.3、4.4、4.11 で述べるとおり、authorization response の内容を attacker に読まれないようにする対策は依然として必要です。

4.6. Access Token Injection

access token injection attack では、attacker は盗んだ access token を、attacker の支配下ではない正当な client に注入しようとします。典型的には、漏えいした access token を使って、特定 client において user を impersonate したい場合に起きます。

この attack を行うため、attacker は implicit grant を使って client と OAuth flow を開始し、authorization response を改変して、authorization server が発行した access token を置き換えるか、または漏えいした access token を含む authorization server response を(勝手に)作り上げます。response には、client がこの transaction 用に生成した state 値が含まれるため、client はそれを CSRF attack と扱わず、attacker が注入した access token を使用してしまいます。

4.6.1. Countermeasures

pure-OAuth flow では、その token が transaction や特定 user agent に何らバインドされないため、この種の injection attack を検出する方法はありません。

OpenID Connect では attack を緩和できます。authorization response には、at_hash claim を含む ID Token が追加で含まれるためです。attacker は access token だけでなく ID Token も置き換える必要があります。attacker は ID Token を forge できません。ID Token は署名されているか、あるいは暗号化され、authentication により保護されているからです。また attacker は、盗んだ access token に一致する漏えい ID Token を注入することもできません。漏えい ID Token の nonce claim は(非常に高い確率で)authorization response で期待される値と異なるためです。

なお、attacker が resource endpoint で access token を直接使用するのを防ぐには、sender-constrained access tokens のような追加保護が依然として必要です。

本書の Section 2.1.2 の推奨はこの点から導かれます。

4.7. Cross-Site Request Forgery

attacker は、victim device 上の正当 client の redirection URI に request を注入しようとする可能性があります。たとえば client に attacker 制御下の resource へアクセスさせる、といった目的です。これは Cross-Site Request Forgery (CSRF) として知られる attack の variant です。

4.7.1. Countermeasures

確立された countermeasure は、client が redirection URI への request を user agent session に結びつけるため、state parameter に random な値(CSRF Token とも呼ばれる)を渡すことです。これは [RFC6819] の Section 5.3.5 で詳細に記述されています。PKCE または OpenID Connect の nonce 値も同等の保護を提供します。

CSRF protection に state や nonce ではなく PKCE を用いる場合、次に注意する必要があります。

  • client は、authorization server が PKCE をサポートしていることを確認してから、PKCE を CSRF protection に使わなければなりません(MUST)。authorization server が PKCE をサポートしない場合、state または nonce を CSRF protection に使用しなければなりません(MUST)。

  • state を application state の運搬に使い、その内容の integrity が懸念される場合、client は state を tampering や swapping から保護しなければなりません(MUST)。これは state の内容を browser session にバインドする、または state 値を署名/暗号化することで実現できます。この例は期限切れ Internet-Draft [JWT-ENCODED-STATE] で議論されています。

したがって authorization server は、自身が PKCE をサポートしていることを検出する方法を提供しなければなりません(MUST)。[RFC8414] による Authorization Server Metadata の利用が RECOMMENDED ですが、authorization server は代わりにデプロイメント固有の方法で PKCE サポートを保証・判定してもよい(MAY)とします。

PKCE は、authorization response の内容を読み取れる attacker(Section 3 の Attacker (A3) 参照)が存在しても、CSRF attack に対する堅牢な保護を提供します。state を使用している場合や、authorization response で ID Token が返る場合(例: response_type=code+id_token)では、attacker は state 値を学習して forged authorization response に replay できたり、ID Token から nonce を抽出して authorization server に新しい request を送り、同じ nonce を持つ ID Token を mint させることができます。新しい ID Token は CSRF attack に利用され得ます。

4.8. PKCE Downgrade Attack

PKCE をサポートするが、すべての flow で PKCE の使用を mandatory にしていない authorization server は、PKCE downgrade attack に対して脆弱であり得ます。

この attack の第 1 の prerequisite は、authorization request の中に、当該 flow に対して PKCE を有効/無効化できる attacker 制御可能な flag が存在することです。code_challenge parameter の有無がこの目的に使われやすいです。すなわち、authorization server がこの parameter が存在する場合は PKCE を有効化して強制し、parameter が欠けている場合は PKCE を強制しない、という設計です。

第 2 の prerequisite は、client が state をまったく使っていない(例: client が CSRF prevention のため PKCE に依存している)か、または client が state を正しく check していないことです。

大まかに言うと、この attack は CSRF attack の variant です。attacker は Section 4.7 の attack と同じ目標を達成します。すなわち、attacker の resource にバインドされた Authorization Code(ひいては access token)を、victim と client の session に注入します。

4.8.1. Attack Description

  1. user は authorization server 上のある client を使って OAuth session を開始しています。authorization request では client は PKCE code challenge として code_challenge=hash(abc) を設定しています(hash function と parameter encoding は [RFC7636] に従う)。client は user の browser から authorization response を受け取るのを待っています。
  2. attack を行うため、attacker は自分の device で対象 client と authorization flow を開始します。client は別の PKCE code challenge、例えば code_challenge=hash(xyz) を authorization request に使います。attacker は request を intercept し、request から code_challenge parameter 全体を削除します。この手順は attacker の device 上で行われるため、attacker は browser debug tool などを使って request 内容へ完全にアクセスできます。
  3. authorization server が PKCE なしの flow を許可している場合、PKCE code challenge にバインドされていない code を作成します。
  4. attacker は user の browser を、attacker の authorization server session に対する code を含む authorization response URL に redirect します。
  5. user の browser は Authorization Code を client に送ります。client はその code を access token と交換しようとして authorization server に token request を送ります。この token request には PKCE code verifier として code_verifier=abc が含まれます。
  6. authorization server はこの code が PKCE code challenge にバインドされていないことを確認すると、code_verifier parameter の有無や内容を check しません。そして client(user の支配下)に対し access token(attacker の resource に属する)を発行します。

4.8.2. Countermeasures

state を正しく用いればこの attack は防げます。しかし実際には、多くの OAuth client が state を使わない、または state を正しく check していないことが示されています。

そのため authorization server はこの attack を緩和しなければなりません(MUST)。

authorization server の観点では、上記の attack においては、authorization request に code_challenge parameter が存在しない OAuth flow で発行された code に対し、token endpoint で code_verifier parameter を含む request が受信されます。

この事実を用いて attack を緩和できます。[RFC7636] はすでに次を義務付けています。

  • PKCE をサポートする authorization server は、authorization request に code challenge が含まれているかを check し、その情報を発行した code にバインドしなければなりません(MUST)。
  • code が token endpoint に到着したとき、その code が発行された authorization request に code_challenge が存在したなら、token request には有効な code_verifier が存在しなければなりません。

これに加え、PKCE downgrade attack を防ぐため、authorization server は次を保証しなければなりません(MUST)。すなわち、authorization request に code_challenge が存在しなかった場合、code_verifier を含む token endpoint への request は拒否されること。

PKCE の使用を mandatory にする authorization server(一般に、または特定 client に対して)は、暗黙的にこのセキュリティ対策を実装することになります。

4.9. Access Token Leakage at the Resource Server

ある状況下では、access token が resource server から漏えいする可能性があります。

4.9.1. Access Token Phishing by Counterfeit Resource Server

attacker は自分の resource server を立ち上げ、client を騙して、他の resource server に対して有効な access token をその偽 resource server に送らせることができます(Section 3 の Attackers (A1) と (A5) 参照)。client が有効な access token を偽 resource server に送ると、attacker はそれを使って resource owner の behalf で他サービスへ access できます。

この attack は、client が開発時点で特定の resource server(およびその URL)にバインドされておらず、resource server URL が runtime に user または administrator により与えられることを前提とします。この種の late binding は、client が標準化された API を実装する service(例: email、calendaring、eHealth、open banking)を利用する状況や、client が user/administrator により設定される状況で典型的です。

4.9.2. Compromised Resource Server

attacker は resource server を侵害し、当該デプロイメントの resource へ access する可能性があります。侵害は、例えば log file への read-only access のような部分的 access から、すべての control が迂回されすべての resource へ access できる完全な control まで幅があります。attacker は侵害された system 上に保持されている他の access token も入手できる可能性があり、それらが別の resource server への access に有効である場合があります。

server breach を防ぐための hardening や monitoring は標準的な運用手順と見なされ、本書の scope 外です。Section 4.9 は OAuth 関連 breach の impact と、capture された access token の replay に焦点を当てます。

4.9.3. Countermeasures

悪意ある actor による access token replay に対処するため、implementer は次の対策を考慮すべきです。

  • Section 4.10.1 で述べる sender-constrained access tokens を使用すべきです(SHOULD)。これにより attacker が別の resource server で access token を replay するのを防げます。attacker の侵害が web server log への read-only access のような部分的なものでも、sender-constrained access tokens は侵害された system 上での replay を防ぐ場合があります。
  • Section 4.10.2 で述べる audience restriction を使用すべきです(SHOULD)。これにより capture された access token の別 resource server での replay を防げます。
  • resource server は access token を他の sensitive secret と同様に扱い、plaintext で保存または転送してはなりません(MUST NOT)。

第 1 および第 2 の推奨は、access token が漏えいする他の scenario(Section 3 の Attacker (A5) 参照)にも適用されます。

4.10. Misuse of Stolen Access Tokens

access token は attacker により、例えば Sections 4.1、4.2、4.3、4.4、4.9 で述べた attack を通じて盗まれ得ます。これらの一部は各 section のセキュリティ対策で緩和できますが、場合によっては不十分だったり、正しく実装されていないことがあります。そのため authorization server は、以下で述べるように access token を sender-constrained かつ audience-restricted にすることを保証すべきです(SHOULD)。ただしアーキテクチャや性能上の理由から、これらの対策をあるデプロイメントで使えない場合もあります。

4.10.1. Sender-Constrained Access Tokens

名称が示す通り、sender-constrained access tokens は、access token の適用可能性を特定の sender に限定します。この sender は、recipient(例: resource server)でその token が受理される前提として、特定 secret の知識を示す義務があります。

典型的な flow は次のとおりです。

  1. authorization server は、access token に、この token を特定 client にバインドする data を関連づけます。この binding は client の identity を用いることもできますが、ほとんどの場合、authorization server は client が知る key material(またはそこから導かれる data)を用います。
  2. この key material は何らかの方法で配布されなければなりません。authorization server が binding を作る前から key material が存在する場合もあれば、authorization server が ephemeral key を作る場合もあります。事前に存在する key material の配布方法は approach により異なります。たとえば X.509 certificate を使う場合、配布は enrollment process 中に明示的に行われます。あるいは key material が TLS layer で作られ配布される場合、TLS connection の setup 中に自動的に起きるかもしれません。
  3. resource server は proof-of-possession check の実装が必要です。これは通常 application level で行われ、transport layer(例: TLS)が提供する特定 material に結びつくことが多いです。また resource server は、proof-of-possession の replay が不可能であることも保証しなければなりません。

OAuth working group により、proof-of-possession を用いる sender-constrained access tokens の 2 つの method が定義され、実運用されています。

  • "OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens" [RFC8705]: この approach は mutual TLS を client authentication と sender-constrained access tokens の両方に利用可能にします。sender-constrained access tokens の目的において、client は自分の public key の fingerprint により resource server に対して識別されます。access token request の処理中、authorization server は TLS stack から client public key を取得し、その fingerprint を当該 access token に関連づけます。resource server も同様に TLS stack から public key を取得し、token に関連づけられた fingerprint と比較します。
  • "OAuth 2.0 Demonstrating Proof of Possession (DPoP)" [RFC9449]: DPoP は application-level mechanism を概説し、sender-constraining を access token と Refresh Token に適用します。public/private key pair に基づく proof-of-possession と application-level 署名を用います。DPoP は Public client で利用でき、confidential client の場合は任意の client authentication method と組み合わせられます。

sender-constrained token の安全性は、attacker が token と key material の両方に access できると損なわれる点に注意が必要です。これは特に、client software の改ざんや、(client が browser 上で動く場合の)XSS attack に当てはまります。key material が hardware / software security module で保護されている場合や、TLS stack のように間接的にしかアクセスできない場合、sender-constrained token は少なくとも「client が offline である」状況、すなわち security module や interface が attacker に利用できない状況では token の使用を防ぎます。この点は access token と Refresh Token の双方に当てはまります(Section 4.14 参照)。

4.10.2. Audience-Restricted Access Tokens

audience restriction は本質的に、access token を特定 resource server に限定します。authorization server は access token を当該 resource server に関連づけ、resource server は intended audience を検証することが期待されます。access token が intended audience validation に失敗すれば、resource server は当該 request の提供を拒否します。

一般に audience restriction は token leakage の impact を限定します。counterfeit resource server の場合には、(以下で述べるように)phished access token の正当 resource server での悪用を防ぐこともできます。

audience は logical name または physical address(URL など)で表現できます。phishing を防ぐには、client が request を送る実際の URL を使う必要があります。phishing の case では、この URL は偽 resource server を指します。attacker がその access token を正当 resource server(別 URL)で使おうとしても、resource server は mismatch(wrong audience)を検出して request を拒否します。

authorization server がすべての resource server の URL を把握しているデプロイメントでは、未知の resource server URL 向けの access token 発行を拒否することもできます。

これを成立させるには、client が intended resource server を authorization server に伝える必要があります。これには [RFC8707] の mechanism を使うか、scope 値([RFC6749] の Section 3.3)に情報を encode できます。

URL の代わりに、resource server の X.509 certificate の fingerprint を audience 値として利用することも可能です。この variant は、別の CA から取得した有効な TLS certificate を用いて正当 resource server URL を spoof する試みの検出にも役立ちます。また resource server URL を authorization server から隠すという privacy 上の利点と考えられるかもしれません。

audience restriction は client 側で暗号を必要としないため使いやすく見えるかもしれません。しかし各 access token は特定 resource server にバインドされるため、client は複数 resource server に access する場合、resource server ごとに token を取得する必要があります。([RFC8707] の resource indicator はこれを助けます。)[TOKEN-BINDING] も同様に、異なる token-binding ID を access token に関連づける必要があるため同じ性質を持ちます。一方、mutual TLS for OAuth 2.0 [RFC8705] は client が複数 resource server で同じ access token を使えるようにします。

audience restriction、あるいは一般に client が authorization server に「どこで access token を使いたいか」を示すことには、token leakage prevention を超えた追加の利点がある点に注意すべきです。authorization server は、その server 向けに format や content を調整した別の access token を作れるようになります。これは structured access token を使うデプロイメントで、機能面および privacy 面で大きな利点を持ちます。

4.10.3. Discussion: Preventing Leakage via Metadata

authorization server が client に、access token を安全に使える location に関する追加情報を提供する、という approach も考えられます。この approach と、なぜ推奨されないかを以下で述べます。

最も単純な形では、authorization server が既知の resource server の list を公開する必要があります。以下は non-standard な Authorization Server Metadata parameter resource_servers を用いた例です。

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

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

authorization server はまた、token response で access token が有効な URL を返すこともできます。以下は例と non-standard return parameter access_token_resource_server です。

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

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

この緩和策は、client が security policy を強制し、正当な宛先にのみ Access Tokens を送ることに依存する。しかし OAuth に関連するセキュリティ研究の結果(例: [research.ubc] と [research.cmu])は、多くの client 実装が state checks のような security controls を実装していない、または適切に実装できていないことを示している。したがって、client に Access Token phishing の防止を任せるのは失敗しがちである。さらに、clients と authorization/resource servers の比率を踏まえると、可能な限り security-related logic を これら servers 側へ移す方が実行可能なアプローチだと考えられる。もちろん client も全体のセキュリティに寄与しなければならない。しかし Sections 4.10.1 と 4.10.2 で述べる代替対策は、 関与者間のバランスがより良い。

4.11. Open Redirection

authorization server または client に open redirector がある場合、次の attack が起こり得ます。このような endpoint は、例えば user を外部 website に redirect する前に message を表示する目的や、login prompt によって中断される前に user が訪れようとしていた URL に戻す目的などで実装されることがあります。

4.11.1. Client as Open Redirector

client は open redirector を公開してはなりません(MUST NOT)。attacker は open redirector を用いて client を指す URL を生成し、Section 4.1.2 で述べたように Authorization Code や access token を流出させることができます。もう 1 つの悪用例は、見かけ上 client を指しているように見える URL を作ることです。これにより user が URL を信頼して browser で開いてしまう可能性があり、phishing に悪用されます。

open redirection を防ぐため、client は target URL が許可されている場合にのみ redirect すべきであり、あるいは request の origin と integrity を認証できる場合にのみ redirect すべきです。open redirection に対する countermeasure は OWASP [owasp.redir] に記載されています。

4.11.2. Authorization Server as Open Redirector

client と同様に、attacker は authorization server(特にその URL)に対する user の信頼を利用して phishing attack を行おうとする可能性があります。OAuth authorization server は通常 user を他の website(client)へ redirect しますが、安全に行わなければなりません。

[RFC6749] の Section 4.1.2.1 は、client_id と redirect_uri の組み合わせが無効な場合、authorization server は user agent を自動 redirect してはならない(MUST NOT)と規定しており、open redirect を防ぎます。

しかし attacker は、正しく登録された redirection URI を使って phishing attack を行うこともできます。例えば attacker は dynamic client registration [RFC7591] により client を登録し、次の attack のいずれかを実行できます。

  1. 意図的に誤った authorization request(例: 無効な scope 値)を送って authorization server に user agent を phishing site に redirect させる。
  2. attacker が制御する client_id と redirect_uri を用いて正しい authorization request を送る。user が authentication した後、authorization server は user に consent を求めます。user が request の問題に気づき request を拒否しても、authorization server は依然として user agent を phishing site へ redirect します。この場合 user agent は user の action に関わらず phishing site へ redirect されます。
  3. attacker が制御する client_id と redirect_uri を用いて、有効な silent authentication request(prompt=none)を送る。この場合 authorization server は user agent を自動的に phishing site に redirect します。

authorization server はこれらの脅威を防ぐための precaution を取らなければなりません(MUST)。authorization server は常にまず user を authenticate し、silent authentication use case を除き、redirect 前に必要に応じて user に credential の入力を求めなければなりません(MUST)。authorization server は risk assessment に基づき、redirection URI を信頼できるかどうかを判断する必要があります。authorization server は、内部または外部 service を通じた URI analytics を考慮し、URI の背後にある content の credibility と trustworthiness を評価してもよいです。また redirection URI の source や他の client data も考慮し得ます。

authorization server は、redirection URI を信頼する場合にのみ user agent を自動 redirect すべきです(SHOULD)。URI が信頼できない場合、authorization server は user に通知し、user が正しい判断をすることに依存してもよい(MAY)とします。

4.12. 307 Redirect

authorization endpoint における典型的な protocol flow では、authorization server が user に credential を form で入力させ、それが(HTTP POST method により)authorization server に submit されます。authorization server は credential を検証し、成功した場合 user agent を client の redirection endpoint に redirect します。

[RFC6749] ではこの目的に HTTP status code 302 (Found) を使いますが、「user-agent を介してこの redirection を達成する他のどの method も許容される」としています。もし status code 307 を redirect に使うと、user agent は user の credential を HTTP POST で client に送ってしまいます。

これは sensitive credential を client に開示します。client が悪意ある場合、credential を使って authorization server 上で user を impersonate できます。

この挙動は developer にとって予期しづらいかもしれませんが、[RFC9110] の Section 15.4.8 で定義されています。status code (307) は user agent に対して、POST request を GET request に書き換えて POST body の form data を落とすことを要求しません。

HTTP standard [RFC9110] では、status code 303 のみが、HTTP POST request を HTTP GET request に書き換えることを明確に強制します。他の status code(一般的な 302 を含む)では、user agent は POST を GET に書き換えず、結果として user credential が client に露出する可能性があります。(実際には、多くの user agent は 307 redirect の場合にのみこの挙動を示します。)

したがって、user credential を含む可能性がある request を redirect する authorization server は、redirect に HTTP 307 status code を使ってはなりません(MUST NOT)。この種の request に HTTP redirection(例えば JavaScript ではなく)を使う場合、authorization server は HTTP status code 303 (See Other) を使用するべきです(SHOULD)。

4.13. TLS Terminating Reverse Proxies

HTTP application の一般的な deployment architecture は、TLS connection を terminate して受信 request を対応する application server node に dispatch する reverse proxy の背後に application server を隠すことです。

この section は、この deployment architecture に関する OAuth に関連するいくつかの attack angle を強調し、security control に関する推奨を示します。

状況によって reverse proxy は、security 関連 data を upstream application server に渡して追加処理させる必要があります。例として request originator の IP address、token-binding ID、認証済み TLS client certificate などがあります。これらの data は通常、upstream request に追加される HTTP header で渡されます。header はしばしば custom / application-specific ですが、client certificate と client certificate chain のための standardized header field が [RFC9440] で定義されています。

reverse proxy が外部から送られた任意の header を pass-through してしまうと、attacker は偽の header 値を proxy 経由で application server に直接送り、security control を迂回しようとする可能性があります。例えば reverse proxy は慣例的に X-Forwarded-For header を受け入れ、inbound request の origin を追加して list にします。application server の logic 次第では、attacker が許可された IP address を header に追加するだけで保護が無意味になるかもしれません。

そのため reverse proxy は、application server の security に関係するすべての header 値の authenticity と integrity を確保するため、inbound request を sanitize しなければなりません(MUST)。

また、attacker が proxy と application server の間の internal network に access できた場合、そこにある security control を迂回しようとする可能性があります。したがって communicating entity の authenticity を確保することが本質的に重要です。さらに reverse proxy と application server の間の communication link は、eavesdropping、injection、replay に対して保護されなければなりません(MUST)。

4.14. Refresh Token Protection

Refresh Token は新しい access token を取得する便利で user-friendly な手段です。また OAuth の security を高めます。というのも authorization server が短い lifetime と縮小した scope の access token を発行できるようになり、access token leakage の潜在的 impact を減らせるからです。

4.14.1. Discussion

Refresh Token は attacker にとって魅力的な target です。なぜなら Refresh Token は特定 client に付与された access の full scope を表し、特定 resource に対してさらに制約されていないからです。attacker が Refresh Token を流出させ、成功裏に replay できれば、attacker は access token を mint し、resource owner の behalf で resource server へ access できます。

[RFC6749] は、次を要求することで強固な baseline protection をすでに提供しています。

  • Refresh Token の transit と storage における confidentiality
  • authorization server と client の間で、TLS 保護された connection を介して Refresh Token を転送すること
  • 可能な場合、authorization server が Refresh Token を特定 client にバインドし、その binding を維持・check し、token refresh 時にその client を authenticate すること
  • Refresh Token が生成・改変・推測できないこと

[RFC6749] はまた、Refresh Token の expiration、revocation、Refresh Token rotation といった(実装依存の)追加 security measure の基盤も提供します。該当 error code と response behavior を定義しているためです。

本仕様は [RFC6749] の範囲を超える推奨と明確化を提供します。

4.14.2. Recommendations

authorization server は risk assessment に基づき、特定 client に Refresh Token を発行するかどうかを決定しなければなりません(MUST)。authorization server が Refresh Token を発行しないと決めた場合、client は authorization code grant type のような他の grant type を利用して新しい access token を取得してもよい(MAY)とします。その場合、authorization server は cookie や persistent grant を利用して user experience を最適化することができます。

Refresh Token を発行する場合、それらの Refresh Token は resource owner が consent した scope と resource server にバインドされなければなりません(MUST)。これは正当 client による privilege escalation を防ぎ、Refresh Token leakage の impact を減らすためです。

confidential client については [RFC6749] がすでに、Refresh Token は発行された client のみにより使用できることを要求しています。

authorization server は Public client 向けに、悪意ある actor による Refresh Token replay を検出するため、次の method のいずれかを使用しなければなりません(MUST)。

  • Sender-constrained refresh tokens: authorization server が Refresh Token を特定 client instance に暗号的にバインドします。例: [RFC8705] または [RFC9449] を利用。
  • Refresh token rotation: authorization server は access token refresh response のたびに新しい Refresh Token を発行します。前の Refresh Token は invalidated されますが、関係性に関する情報は authorization server に保持されます。もし Refresh Token が侵害され、その後 attacker と正当 client の双方により使用された場合、どちらか一方は invalidated された Refresh Token を提示し、それにより authorization server は侵害を把握できます。authorization server はどちらが invalidated token を送ったかを判断できませんが、active な Refresh Token を revoke します。これにより attack は止まりますが、正当 client に新しい authorization grant の取得を強いる cost が生じます。

Implementation note: Refresh Token が属する grant を Refresh Token 自体に encode できます。これにより authorization server は、Refresh Token が属する grant(ひいては revoke すべき Refresh Token 群)を効率的に特定できます。この場合 authorization server は Refresh Token 値の integrity を保証しなければなりません(MUST)。たとえば signature を用います。

authorization server は、次のような security event の場合に Refresh Token を自動的に revoke してもよい(MAY)とします。

  • password change
  • authorization server での logout

Refresh Token は、client が一定期間 inactive だった場合に expire するべきです(SHOULD)。すなわち、一定期間その Refresh Token が新しい access token を得るために使用されていない場合です。expiration time は authorization server の裁量です。global な値でもよいし、client policy または Refresh Token に関連づく grant(およびその sensitivity)に基づいて決めてもよいです。

4.15. Client Impersonating Resource Owner

resource server は、access token が発行された resource owner の identity に基づいて access control decision を行う場合があります。または client credentials grant における client identity に基づく場合もあります。例えば [RFC9068](OAuth 2.0 Access Tokens の JSON Web Token (JWT) Profile)は、sub claim を含む access token の data structure を次のように記述します。

In cases of access tokens obtained through grants where a resource
owner is involved, such as the authorization code grant, the value
of "sub" SHOULD correspond to the subject identifier of the
resource owner.  In cases of access tokens obtained through grants
where no resource owner is involved, such as the client
credentials grant, the value of "sub" SHOULD correspond to an
identifier the authorization server uses to indicate the client
application.

両方の option があり得る場合、resource server は client identity を resource owner identity と誤認する可能性があります。例えば、authorization server への registration 時に client が自分の client_id を選べる場合、悪意ある client はそれを resource owner を識別する値(例: OpenID Connect を使う場合の sub 値)に設定できます。resource server が resource owner の関与がある access token と、関与がない access token を適切に区別できなければ、client が誤って resource owner の resource に access できてしまう可能性があります。

この attack は [RFC9068] を用いる実装だけでなく、類似の bespoke solution にも影響し得ます。

4.15.1. Countermeasures

authorization server は、client ID と user identifier のための共通 namespace が存在する場合(Section 4.15 の [RFC9068] の sub claim 例のように)、正当な resource owner と混同され得る client_id やその他 claim に client が影響を与えられるようにすべきではありません(SHOULD NOT)。それを避けられない場合、authorization server は resource server が 2 種類の access token を区別できる他の手段を提供しなければなりません(MUST)。

4.16. Clickjacking

[RFC6819] の Section 4.4.1.9 で述べたとおり、authorization request は clickjacking attack(user interface redressing とも呼ばれる)に対して脆弱です。この attack では attacker が authorization endpoint の user interface を無害な文脈に埋め込みます。user はその文脈と対話しているつもりで、例えば button を click するなどして、意図せず authorization endpoint の user interface と対話してしまいます。逆も可能です。user が authorization endpoint と対話しているつもりでも、attacker が提供する input field が元の user interface の上に重ねられており、user が attacker に password を入力してしまう、といったケースです。clickjacking attack は user がほとんど気づけないよう設計でき、例えば他の element の上にほとんど見えない iframe を重ねるなどが可能です。

attacker はこの vector を用いて user の authentication credential を入手し、client に付与される access scope を変更し、潜在的に user の resource に access できます。

authorization server は clickjacking attack を防がなければなりません(MUST)。[RFC6819] では X-Frame-Options HTTP response header field や frame-busting JavaScript の使用など複数の countermeasure が述べられています。それらに加え authorization server は Content Security Policy (CSP) level 2 [W3C.CSP-2] 以上も使用すべきです(SHOULD)。

効果的であるために、CSP は authorization endpoint に加え、必要に応じて user を authenticate したり client を authorize するために使われる他の endpoint(例: device authorization endpoint、login page、error page など)にも適用されなければなりません。これにより CSP をサポートする user agent で、未承認 origin による framing を防ぎます。client は、自身の redirection endpoint で使う origin と異なる origin からの framing を許可してもよい(MAY)とします。この理由から、authorization server は administrator が特定 client に許可する origin を設定できるようにする、または client がそれらを動的に register できるようにするべきです(SHOULD)。

CSP を使うと authorization server は単一の response header field に複数 origin を指定でき、柔軟な pattern で制約できます(詳細は [W3C.CSP-2] 参照)。CSP level 2 は、frame の origin を制限する policy(frame-ancestors)と、HTML page 上で実行を許可する script の source を制限する policy(script-src)を組み合わせることで、clickjacking に対する堅牢な mechanism を提供します。以下に non-normative な policy example を示します。

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

一部 user agent は [W3C.CSP-2] をサポートしないため、この technique は [RFC6819] で述べるものを含む他の countermeasure と組み合わせるべきです(SHOULD)。ただし、authorization server がそのような legacy user agent を明示的にサポートしない場合を除きます。たとえその場合でも追加の countermeasure は依然として用いられるべきです(SHOULD)。

4.17. Attacks on In-Browser Communication Flows

authorization response が HTTP redirect の代わりに postMessage [WHATWG.postmessage_api] のような in-browser communication technique で送られる場合、message が意図せず悪意ある origin に送られたり、悪意ある origin から注入される可能性があります。

4.17.1. Examples

次の in-browser communication を用いた attack の non-normative pseudocode example は [research.rub] で述べられています。

4.17.1.1. Insufficient Limitation of Receiver Origins

postMessage で authorization response または token response を送る際、authorization server が client origin の代わりに wildcard origin "*" に response を送るケースです。response を送る先 window が attacker により control される場合、attacker は response を読み取れます。

window.opener.postMessage(
  {
    code: "ABC",
    state: "123",
  },
  "*", // opener window のどの website でも message を受信できる
);

4.17.1.2. Insufficient URI Validation

postMessage で authorization response または token response を送る際、authorization server が receiver origin を redirection URI に対して check せず、例えば attacker が提供した origin に response を送ってしまうケースです。これは Section 4.1 で述べた attack に類似しています。

window.opener.postMessage(
  {
    code: "ABC",
    state: "123",
  },
  "https://attacker.example", // attacker 提供の値
);

4.17.1.3. Injection after Insufficient Validation of Sender Origin

postMessage 経由で authorization response または token response を期待する client が、message の sender origin を validate しないケースです。これにより attacker が client に authorization response または token response を inject できてしまいます。

悪意ある authorization response が注入される場合、この attack は Section 4.7 で述べた CSRF attack の variant です。Section 4.7 で述べる countermeasure はこの attack にも適用されます。

悪意ある token response が注入される場合、Section 4.10.1 で述べる sender-constrained access tokens が状況によっては attack を防ぐかもしれませんが、一般には Section 4.17.2 で述べる追加 countermeasure が必要です。

4.17.2. Recommendations

client receiver origin を pre-registered origin と比較する際、authorization server は Section 4.1.3 で述べた exact string matching を用いなければなりません(MUST)。authorization server は、次の non-normative example に示すように、trusted client receiver origin に postMessage を送らなければなりません(MUST)。

window.opener.postMessage(
  {
    code: "ABC",
    state: "123",
  },
  "https://client.example", // 明示的な client origin を使用
);

postMessage で "*" のような wildcard origin は使用してはなりません(MUST NOT)。attacker がこれを用いて victim の in-browser message を悪意ある origin に漏えいさせられるためです。これら 2 つの対策は、Section 4.1 で述べる Authorization Code と access token の leakage prevention に寄与します。

client は client receiver endpoint における in-browser message の注入を防がなければなりません(MUST)。client は次の non-normative example のように、in-browser message の initiator origin を authorization server origin と比較するために exact string matching を用いなければなりません(MUST)。

window.addEventListener("message", (e) => {
  // authorization server origin を厳密一致で検証
  if (e.origin === "https://honest.as.example") {
    // e.data.code と e.data.state を処理
  }
});

in-browser communication flow は communication technique(HTTP redirect ではなく postMessage)を変えるだけなので、Section 2.1 に列挙された authorization response を保護するすべての対策は、同様に適用されなければなりません(MUST)。

5. IANA Considerations

本書には IANA action はありません。

6. Security Considerations

Security considerations は Sections 2、3、4 で記述されています。

7. References

7.1. Normative References

(この section は reference の列挙のため、内容は原文のままです)

7.2. Informative References

(この section は reference の列挙のため、内容は原文のままです)

Acknowledgements

We would like to thank Brock Allen, Annabelle Richard Backman, Dominick Baier, Vittorio Bertocci, Brian Campbell, Bruno Crispo, William Dennis, George Fletcher, Matteo Golinelli, Dick Hardt, Joseph Heenan, Pedram Hosseyni, Phil Hunt, Tommaso Innocenti, Louis Jannett, Jared Jennings, Michael B. Jones, Engin Kirda, Konstantin Lapine, Neil Madden, Christian Mainka, Jim Manico, Nov Matake, Doug McDorman, Karsten Meyer zu Selhausen, Ali Mirheidari, Vladislav Mladenov, Kaan Onarioglu, Aaron Parecki, Michael Peck, Johan Peeters, Nat Sakimura, Guido Schmitz, Jörg Schwenk, Rifaat Shekh-Yusef, Travis Spencer, Petteri Stenius, Tomek Stojecki, David Waite, Tim Würtele, and Hans Zandbelt for their valuable feedback.

Authors' Addresses

Torsten Lodderstedt\ SPRIND\ Email: torsten@lodderstedt.net

John Bradley\ Yubico\ Email: ve7jtb@ve7jtb.com

Andrey Labunets\ Independent Researcher\ Email: isciurus@gmail.com

Daniel Fett\ Authlete\ Email: mail@danielfett.de