1. はじめに
この節は規範的ではありません。
多くのユーザーエージェントは、Cookie に保存された非同一サイトデータへのコンテンツからのアクセスを防止します。 これにより、非同一サイト Cookie へのアクセスに依存する埋め込みコンテンツが機能しなくなる可能性があります。
requestStorageAccessFor API を使用すると、開発者は iframe、
スクリプト、画像などの埋め込みリソースについて、非同一サイト Cookie へのアクセスを要求できます。
これは、requestStorageAccessFor(requestedOrigin)
を規定することによって実現されます。このメソッドにより、トラバーサブルナビゲーション可能は、別のオリジンに代わって、非分割 Cookie へのアクセスを要求できます。
2. 基盤
この仕様は Infra 標準に依存します。[INFRA]
3. requestStorageAccessFor API
この仕様は、別のオリジンに代わって非分割データへのアクセスを要求するために使用できるメソッド
(requestStorageAccessFor(requestedOrigin))を定義します。
Alex が https://social.example/ にアクセスします。ページは Cookie を設定します。この Cookie は
ファーストパーティサイトコンテキストで設定されています。
その後、Alex は https://video.example/ にアクセスします。このページには
https://social.example/profile-image を読み込む
img
があります。この場合、social.example の Document
doc はサードパーティコンテキストにあり、以前に設定された Cookie が
doc.cookie
から参照できるかどうかは、ユーザーエージェントのストレージアクセス方針によって異なります。
https://video.example/ 上のスクリプトは、USVString
requestedOrigin に https://social.example を指定して
doc.requestStorageAccessFor(requestedOrigin)
を呼び出すことで、https://social.example に代わってアクセスを要求できます。
注: アクセスを使用する状況は、要求されたオリジンが共有をオプトインする場合に限定する必要があります。詳細については、 § 7 プライバシーに関する考慮事項および§ 8 セキュリティに関する 考慮事項を参照してください。
非分割データとは、 サイトが ファーストパーティサイトコンテキストで読み込まれた場合に利用できるクライアント側ストレージです。
Document
がトラバーサブルナビゲーション可能のアクティブな文書である場合、その文書はファーストパーティサイトコンテキストにあります。それ以外の場合でも、
その文書がアクティブな文書であり、その関連する設定オブジェクトのオリジンとトップレベルオリジンが互いに同一サイトである場合、その文書はファーストパーティサイトコンテキストにあります。
Document
がファーストパーティサイトコンテキストにない場合、その文書はサードパーティ
コンテキストにあります。
3.1. Document
への変更
partial interface Document {Promise <undefined >requestStorageAccessFor (USVString ); };requestedOrigin
Document
doc に対して USVString
requestedOrigin を指定して呼び出された場合、requestStorageAccessFor(requestedOrigin)
メソッドは、次の手順を実行しなければなりません。
-
p を新しい Promiseとします。
-
doc が完全にアクティブでない場合、p を「
InvalidStateError」DOMExceptionで拒否し、 p を返します。 -
doc のノードナビゲーション可能がトラバーサブルナビゲーション可能でない場合、 p を「
NotAllowedError」DOMExceptionで拒否し、 p を返します。 -
doc のオリジンが不透明なオリジンである場合、p を「
NotAllowedError」DOMExceptionで拒否し、 p を返します。 -
doc の関連するグローバルオブジェクトがセキュアコンテキストでない場合、p を「
NotAllowedError」DOMExceptionで拒否し、 p を返します。 -
parsedURL を、requestedOrigin に対してURL パーサーを実行した結果とします。
-
origin を parsedURL のオリジンとします。
-
origin が不透明なオリジンである場合、p を「
NotAllowedError」DOMExceptionで拒否し、 p を返します。 -
descriptor を、新しく作成された
TopLevelStorageAccessPermissionDescriptorとします。そのnameは「top-level-storage-access」 に設定し、requestedOriginは origin に設定します。 -
has activation を、doc の
Windowオブジェクトが一時的なアクティベーションを持つ場合は true、 それ以外の場合は false とします。 -
次の手順を並行して実行します。
-
settings を doc の関連する設定オブジェクトとします。
-
global を doc の関連するグローバルオブジェクトとします。
-
existing state を、settings における descriptor の許可状態とします。
-
existing state が許可済みである場合:
-
global を指定し、許可タスクソース上で、 p を解決するグローバルタスクをキューに追加します。
-
返します。
-
-
existing state が拒否済みである場合:
-
doc の
Windowオブジェクトが一時的なアクティベーションを持つ場合、 それを使用してユーザーアクティベーションを消費します。 -
global を指定し、許可タスクソース上で、 p を「
NotAllowedError」DOMExceptionで拒否するグローバルタスクをキューに追加します。 -
返します。
-
-
doc のノードナビゲーション可能がトラバーサブルナビゲーション可能であることを表明します。
-
has activation が false である場合:
-
global を指定し、許可タスクソース上で、 p を「
NotAllowedError」DOMExceptionで拒否するグローバルタスクをキューに追加します。 -
返します。
-
-
permissionState を、descriptor を使用して「
top-level-storage-access」 の使用許可を要求した結果とします。注: 許可を要求し、プロンプトを表示するかどうかを決定するとき、 ユーザーエージェントは、エンドユーザー体験を形成するために実装定義の動作を適用することに注意してください。特に
top-level-storage-accessについては、ユーザーエージェントが、プロンプトを表示せずに 許可を付与または拒否する独自の規則を適用することが知られています。 -
permissionState が許可済みである場合:
-
global を指定し、許可タスクソース上で、 p を解決するグローバルタスクをキューに追加します。
-
返します。
-
-
doc の
Windowオブジェクトが一時的なアクティベーションを持つ場合、 それを使用してユーザーアクティベーションを消費します。 -
global を指定し、許可タスクソース上で、 p を「
NotAllowedError」DOMExceptionで拒否するグローバルタスクをキューに追加します。
-
-
p を返します。
許可タスク ソースを直接使用すべきではありません。[privacycg/requestStorageAccessFor Issue #15]
3.2. ユーザーエージェントのトップレベルストレージアクセス方針
-
settings を、request のクライアントの関連するグローバルオブジェクトの関連する設定オブジェクトとします。
-
descriptor を、新しく作成された
TopLevelStorageAccessPermissionDescriptorとします。そのnameは「top-level-storage-access」 に設定し、requestedOriginは embedded origin に設定します。 -
existing state を、settings における descriptor の許可状態とします。
-
existing state が許可済み である場合、true を返します。
-
false を返します。
4. Permissions との統合
requestStorageAccessFor API は、名前「top-level-storage-access」によって識別される強力な機能を定義します。これは、次の許可関連アルゴリズムを定義します。
PermissionDescriptor-
「
top-level-storage-access」強力な機能は、PermissionDescriptorを次のように定義します。dictionary :TopLevelStorageAccessPermissionDescriptor PermissionDescriptor {USVString = ""; };requestedOrigin - 許可照会アルゴリズム
-
PermissionDescriptorpermissionDesc とPermissionStatusstatus が与えられたとき、「top-level-storage-access」 許可を照会するには、次の手順を実行します。 - 許可キー型
-
「
top-level-storage-access」 機能の許可キーは、サイト型です。注:
requestedOriginフィールドにより、許可ストアエントリが二重キー化されます。 - 許可キー生成アルゴリズム
-
オリジン origin とオリジン embedded origin が与えられたとき、 「
top-level-storage-access」 機能の新しい許可キーを生成するには、次の手順を実行します。-
embedded origin が origin と同一サイトでない場合、null を返します。
-
origin からサイトを取得した結果を返します。
注: embedded origin が origin と同一サイトであるかどうかの検査は、 クロスサイトフレームからの許可照会を禁止することを意図しています。 これは、
top-level-storage-access許可リクエストがトップレベル閲覧コンテキストでのみ許可されるという不変条件に依存します。したがって、 この検査はquery(permissionDesc)でのみ関係します。
-
- 許可キー比較アルゴリズム
-
「
top-level-storage-access」 機能について許可キー key1 と key2 を 比較するには、次の手順を実行します。-
key1 が null であるか、key2 が null である場合、false を返します。
-
key1 が key2 と同一サイトであるかどうかを返します。
-
5. Fetch との統合
requestStorageAccessFor(requestedOrigin)
は、トップレベル文書から要求されたオリジンへのサブリソースリクエストにおける Cookie の動作にのみ直接影響します。
-
has top-level access を、request に対してリクエストが トップレベルストレージアクセスを持つかどうかを判定した結果とします。
-
has top-level access が false である場合、false を返します。
-
is subresource を、request がサブリソースリクエストである場合は true、 それ以外の場合は false とします。
-
allowed subresource mode を、request のモードが "cors" であり、かつ request の資格情報モードが "include" である場合は true、それ以外の場合は false とします。
-
is subresource が true で、allowed subresource mode が false である場合、false を返します。
-
request のクライアントの関連するグローバルオブジェクトの関連付けられた文書がトラバーサブルナビゲーション可能でない場合、false を返します。
-
true を返します。
6. Storage Access API との統合
注: requestStorageAccessFor(requestedOrigin)
の呼び出しが成功した後でも、フレームは Cookie にアクセスするために requestStorageAccess()
を明示的に呼び出す必要があります。
この変更により、requestStorageAccessFor(requestedOrigin)
は、以前に成功した requestStorageAccess()
の許可と同様に、requestStorageAccess()
の呼び出しを解決できるようになります。
requestStorageAccess()
を変更して、手順 13.4 の前、すなわち一時的なアクティベーションを検査する前に、次の手順を挿入します。
-
settings を doc の関連する設定オブジェクトとします。
-
origin を settings のオリジンとします。
-
descriptor を、新しく作成された
TopLevelStorageAccessPermissionDescriptorとします。そのnameは「top-level-storage-access」 に設定し、requestedOriginは origin に設定します。 -
descriptor の許可状態が許可済み である場合、global を指定し、許可タスクソース上で、p を解決するグローバルタスクをキューに追加し、返します。
-
descriptor の許可状態が拒否済み である場合、global を指定し、許可タスクソース上で、p を「
NotAllowedError」DOMExceptionで拒否するグローバルタスクをキューに追加し、返します。
7. プライバシーに関する考慮事項
[STORAGE-ACCESS]
と同様に、requestStorageAccessFor(requestedOrigin)
は、クロスサイト Cookie の削除を可能にすることを意図しています。このメソッドにより、開発者は追加の制約の下で
クロスサイト Cookie を再取得できます。
注: Storage Access API § 6 プライバシーに関する考慮事項と同じ考慮事項の多くが適用されます。この節では、主に相違点を扱います。
requestStorageAccess()
では、埋め込み文書との対話が必要です。トップレベル文書との対話のみを要求することにより、requestStorageAccessFor(requestedOrigin)
は潜在的なプロンプト表示の条件を緩和しますが、埋め込み文書も非常に目立つものにしたり、ユーザー操作を得るために別の
技法を使用したりできます。
実装定義の受諾手順と拒否手順は、ユーザーエージェントが適切と判断するロジックに基づいて
悪用的なリクエストを拒否できるようにすることを意図しています。
使用するプロンプトは、ユーザーが誰によるアクセス要求なのかを理解できるよう、要求の方向を明確に示す必要があります。
requestStorageAccess()
と同様に、requestStorageAccessFor(requestedOrigin)
にも、ユーザーの同意とプロンプト疲れの間に同じ緊張関係があります。Storage Access API とほぼ同様に、
実装定義の受諾手順と拒否手順は、この問題について異なる立場を持つ実装者が、
適切と判断する妥協を行えるようにすることを意図しています。
もう一つの違いは、コンテキストによっては許可の照会がより機密性の高いものになり得ることです。フレームは、次のいずれの状態も 要求できないようにする必要があることに注意してください。
-
トップレベル文書であったとき、あるオリジンについて「
top-level-storage-access」 許可が付与されたかどうか。 -
現在のトップレベルサイト上で、任意の別のオリジンに「
top-level-storage-access」 が付与されたかどうか。
前者の場合、偽のドメインまたはその組み合わせを識別子として使用できるようになります。後者の場合、無関係なオリジン下の状態が 公開されることになります。
8. セキュリティに関する考慮事項
requestStorageAccessFor(requestedOrigin)
が、クロスサイト Cookie の削除後と比較した場合であっても、ウェブプラットフォームのセキュリティ特性を低下させないことが重要です。
サードパーティ Cookie の削除には、認証済みリクエストに依存する攻撃、たとえば CSRF を軽減するという点で、
セキュリティ上の潜在的な利点があります。
requestStorageAccessFor(requestedOrigin)
が、そのような攻撃に利用される足掛かりになることは望ましくありません。
注: Storage Access API § 7
セキュリティに関する考慮事項の特性は、この提案の大部分に適用されます。具体的には、フレームレベルのアクセスは、
requestStorageAccess()
が正常に呼び出された後にのみ付与されます。
フレームアクセスについて、requestStorageAccessFor(requestedOrigin)
は、アクティベーションおよびプロンプトの要件を簡略化するだけです。
requestStorageAccessFor(requestedOrigin)
は、トップレベル文書によって行われるサブリソースリクエストと、通知の悪用の可能性という二つの領域で、懸念の範囲を拡大します。
8.1. サブリソースリクエスト
この API によって提案される具体的なセキュリティ制御は、次のとおりです。
-
サブリソースリクエストに含まれるすべての Cookie は、
SameSite=Noneと明示的に指定され、 サードパーティコンテキストで使用する意図を示す必要があります。 -
SameSite=NoneCookie を含めるには、リクエストのモードが "cors" である必要があります。この場合、埋め込まれる側が適切な `access-control-allow-credentials` ヘッダーを送信してオプトインしない限り、レスポンスの読み取りはブロックされます。 `origin` ヘッダーを送信することで、埋め込まれる側は埋め込む側の身元を把握できます。
さらに、トップレベル文書から開始されたリクエストのみが、SameSite=None Cookie を含める対象となります。
これにより、他の埋め込みフレームが昇格された権限を受け取らないことが保証されます。
8.2. 通知の悪用
[STORAGE-ACCESS] とは異なり、埋め込み文書ではなくトップレベル文書との対話のみが必要です。 これにより、プロンプトが表示される可能性は高まります。
Storage Access API と同様に、拒否時にはユーザーアクティベーションが消費されるため、リクエストの繰り返しが防止されます。
実装定義の拒否手順により、悪用する主体に対して数値的な制限や拒否リストを適用することもできます。
§ 7 プライバシーに関する考慮事項で述べたように、リクエストの方向性を考慮し、 ユーザーエージェントのプロンプトの文言では、どのサイトがストレージアクセスリクエストを開始したかを示す必要があります。