権限ポリシーでブラウザの機能を管理する

ページとページ上のサードパーティの iframe がブラウザ機能にアクセスする方法の管理。

Kevin K. Lee
Kevin K. Lee

権限ポリシー(旧称: 機能ポリシー)を使用すると、デベロッパーはブラウザが適用する一連のポリシーを宣言することで、ページ、その iframe、サブリソースで使用可能なブラウザ機能を制御できます。これらのポリシーは、レスポンス ヘッダーの送信元リストで指定された送信元に適用されます。オリジンリストには、同一オリジンまたはクロスオリジンを含めることができ、デベロッパーはブラウザ機能へのファーストパーティとサードパーティのアクセスを制御できます。

より高度な機能へのアクセスを許可するかどうかはユーザーが最終的に決定します。プロンプトを承認して明示的な権限を付与する必要があります。

権限ポリシーを使用すると、トップレベル サイトは自身とサードパーティが使用するものを定義でき、機能アクセス リクエストが正当かどうかを判断するユーザーの負担が軽減されます。たとえば、権限ポリシーを使用してすべてのサードパーティに対して位置情報機能をブロックすることで、デベロッパーは、どのサードパーティもユーザーの位置情報にアクセスできないことを確実にできます。

権限に関するポリシーの変更

権限ポリシーは以前「機能ポリシー」と呼ばれていました。主なコンセプトは同じですが、名称とともに重要な変更がいくつかあります。

構造化フィールドの使用

構造化フィールドは、HTTP ヘッダー フィールド値の解析とシリアル化を標準化するための一般的なデータ構造のセットを提供します。構造化フィールドの詳細については、Fastly のブログ投稿「構造化ヘッダー フィールドによる HTTP の改善」をご覧ください。

  geolocation 'self' https://example.com; camera 'none'

機能ポリシーを使用した場合。

新規
  geolocation=(self "https://example.com"), camera=()

権限ポリシーが追加されました。

ヘッダーを iframe allow 属性と組み合わせる

Feature Policy では、ヘッダーのオリジンリストにオリジンを追加するか、iframe タグに allow 属性を追加することで、クロスオリジン フレームに機能を追加できます。権限ポリシーでは、オリジンリストにクロスオリジン フレームを追加する場合、そのオリジンの iframe タグに allow 属性を含める必要があります。レスポンスに権限ポリシー ヘッダーが含まれていない場合、オリジンリストはデフォルト値の * とみなされます。iframe に allow 属性を追加すると、この機能にアクセスできるようになります。

そのため、allow が存在する場合でも、オリジンリストにないクロスオリジン iframe がこの機能にアクセスできないように、レスポンスで権限ポリシー ヘッダーを明示的に設定することをおすすめします。

Chrome 88 以降も Feature Policy は使用できますが、権限ポリシーのエイリアスとして機能します。構文以外にロジックの違いはありません。Permissions Policy ヘッダーと Feature Policy ヘッダーの両方が一緒に使用されている場合、Permissions-Policy ヘッダーの優先度が高く、Feature-Policy ヘッダーで指定された値が上書きされます。

権限ポリシーを使用するにはどうすればよいですか?

概要

詳細に入る前に、ウェブサイトの所有者として、サイトやサードパーティのコードによるブラウザ機能の使用方法を管理する必要があるという一般的なシナリオを見てみましょう。

  • お客様のサイトは https://your-site.example です。
  • サイトに同一オリジン(https://your-site.example)の iframe が埋め込まれています。
  • 信頼できる https://trusted-site.example の iframe がサイトに埋め込まれている。
  • お客様のサイトには、https://ad.example が配信する広告も表示されています。
  • 広告ではなく、自社のサイトと信頼できるサイトに対してのみ位置情報の使用を許可したい。

この場合は、次のヘッダーを使用します。

Permissions-Policy: geolocation=(self "https://trusted-site.example")

信頼できるサイトの iframe タグに allow 属性を明示的に設定します。

<iframe src="https://trusted-site.example" allow="geolocation">

権限ポリシーの使用に関する概要。

この例では、ヘッダーのオリジンリストにより、サイト(self)と trusted-site.example のみが位置情報機能を使用できます。ad.example は位置情報の使用を許可されていません。

  1. お客様のサイト your-site.example は、ユーザーの同意を得て位置情報機能を使用できます。
  2. 同じオリジンの iframe(your-site.example)は、allow 属性を使用せずにこの機能を使用できます。
  3. オリジンリストに追加されていない別のサブドメイン(subdomain.your-site-example)から配信され、iframe タグに allow 属性が設定されている iframe は、この機能の使用がブロックされます。異なるサブドメインは、同一サイトのクロスオリジンと見なされます。
  4. オリジンリストに追加され、iframe タグに allow 属性が設定されているクロスオリジン iframe(trusted-site.example)は、この機能を使用できます。
  5. allow 属性なしでオリジンリストに追加されたクロスオリジン iframe(trusted-site.example)は、この機能の使用がブロックされます。
  6. オリジンリストに追加されていないクロスオリジン iframe(ad.example)は、iframe タグに allow 属性が含まれていても、この機能の使用がブロックされます。

Permissions-Policy HTTP レスポンス ヘッダー

ユーザーがリクエストを行うと、サーバーが Permissions Policy ヘッダーで応答し、ブラウザはそのヘッダーに基づいてアクセスを許可します。

Permissions-Policy: <feature>=(<token>|<origin(s)>)

サーバーからのレスポンスの Permissions-Policy ヘッダーを使用して、特徴の許可されたオリジンを設定します。ヘッダー値には、オリジンのトークンと文字列を組み合わせて指定できます。使用可能なトークンは、すべてのオリジンの場合は *、同じオリジンの場合は self です。

ヘッダーが複数の特徴に対応している場合は、特徴をカンマで区切ります。複数の発行元を指定する場合は、発行元リスト内の各発行元をスペースで区切ります。クロスオリジン リクエストのオリジンがリストされたヘッダーの場合、iframe タグに allow 属性を含める必要があります。

次に、Key-Value ペアの例を示します。

  • 構文: [FEATURE]=*
    • すべてのオリジンに適用されるポリシー
    • 例: geolocation=*
  • 構文: [FEATURE]=(self)
    • 同じオリジンに適用されるポリシー
    • 例: geolocation=(self)
  • 構文: [FEATURE]=(self [ORIGIN(s)])
    • 同じ送信元と指定された送信元に適用されるポリシー
    • 例: geolocation=(self "https://a.example" "https://b.example")
    • selfhttps://your-site.example の省略形です。
  • 構文: [FEATURE]=([ORIGIN(s)])
    • 同じ送信元と指定された送信元に適用されるポリシー
    • 例: geolocation=("https://your-site.example" "https://a.example" "https://b.example")
    • この構文を使用する場合は、いずれかのオリジンを埋め込み元のオリジンにする必要があります。埋め込みページ自体に権限が付与されていない場合、そのページに埋め込まれた iframe は、オリジンリストに追加されているにもかかわらず、権限ポリシーによって権限が委任されるため、ブロックされます。self トークンを使用することもできます。
  • 構文: [FEATURE]=()
    • すべてのオリジンで機能がブロックされている
    • 例: geolocation=()

異なるサブドメインとパス

https://your-site.examplehttps://subdomain.your-site.example など、異なるサブドメインは同一サイトのクロスオリジンと見なされます。したがって、オリジンリストにサブドメインを追加しても、同じサイトの別のサブドメインにアクセスすることはできません。この機能を使用するすべての埋め込みサブドメインを、オリジン リストに個別に追加する必要があります。たとえば、ユーザーのブラウジング トピックへのアクセスが、ヘッダー Permissions-Policy: browsing-topics=(self) でのみ同じオリジンに許可されている場合、同じサイトの別のサブドメイン(https://subdomain.your-site.example)の iframe はトピックにアクセスできません。

異なるパス(https://your-site.examplehttps://your-site.example/embed など)は同一オリジンと見なされ、オリジン リストに異なるパスを含める必要はありません。

iframe の allow 属性

iframe の設定

クロスオリジンで使用する場合、iframe でこの機能にアクセスするには、タグ内に allow 属性を含める必要があります。

構文: <iframe src="[ORIGIN]" allow="[FEATURE] <'src' | [ORIGIN(s)]"></iframe>

例:

<iframe src="https://trusted-site.example" allow="geolocation">

iframe ナビゲーションを処理する

iframe ナビゲーションの設定

デフォルトでは、iframe が別のオリジンに移動した場合、iframe が移動したオリジンにはポリシーが適用されません。iframe が移動するオリジンを allow 属性にリストすることで、元の iframe に適用された権限ポリシーが、iframe が移動するオリジンに適用されます。

<iframe src="https://trusted-site.example" allow="geolocation https://trusted-site.example https://trusted-navigated-site.example">

実際の動作は、iframe ナビゲーション デモでご確認いただけます。

権限ポリシーの設定例

次の設定の例については、デモをご覧ください。

すべてのオリジンで許可される機能

機能へのアクセスが許可されているすべてのオリジンのアーキテクチャ

Permissions-Policy: geolocation=*
<iframe src="https://trusted-site.example" allow="geolocation">
<iframe src="https://ad.example" allow="geolocation">

オリジン リストが * トークンに設定されている場合、この機能はページに存在するすべてのオリジン(そのページ自体とすべての iframe を含む)で許可されます。この例では、https://your-site.example から配信されるすべてのコードと、https://trusted-site.example iframe および https://ad.example から配信されるコードに、ユーザーのブラウザの位置情報機能へのアクセス権があります。ヘッダーのオリジン リストにオリジンを追加するとともに、iframe 自体にも allow 属性を設定する必要があります。

この設定はデモで確認できます。

同じオリジンでのみ許可される機能

同じオリジンのみが機能にアクセスできるアーキテクチャ

Permissions-Policy: geolocation=(self)

self トークンを使用すると、同じオリジンへの位置情報の使用のみが許可されます。クロスオリジンは、この機能にアクセスできません。この例では、https://trusted-site.exampleself)のみが位置情報にアクセスできます。この構文は、自分のページにのみこの機能を適用する場合に使用します。

この設定はデモで確認できます。

同一オリジンと特定のクロスオリジンで許可される機能

機能へのアクセスが許可されている指定されたオリジンのアーキテクチャ

Permissions-Policy: geolocation=(self "https://trusted-site.example")

この構文を使用すると、自己(https://your-site.example)と https://trusted-site.example の両方に位置情報の使用を許可できます。iframe タグには、allow 属性を明示的に追加してください。<iframe src="https://ad.example" allow="geolocation"> を含む別の iframe がある場合、https://ad.example は位置情報機能にアクセスできません。元のページと、iframe タグで allow 属性があり、オリジンリストにある https://trusted-site.example のみがユーザーの機能にアクセスできます。

この設定はデモで確認できます。

機能はすべてのオリジンでブロックされています

この機能へのアクセスがブロックされているすべてのオリジンのアーキテクチャ

Permissions-Policy: geolocation=()

オリジンのリストが空の場合、すべてのオリジンでこの機能がブロックされます。この設定はデモで確認できます。

JavaScript API を使用する

フィーチャー ポリシーの既存の JavaScript API は、ドキュメントまたは要素(document.featurePolicy or element.featurePolicy)のオブジェクトとして見つかります。権限ポリシーの JavaScript API はまだ実装されていません。

Feature Policy API は、権限ポリシーで設定されたポリシーに使用できますが、一部の制限があります。JavaScript API の実装については不明な点が残っています。このロジックを Permissions API に移動する提案が提出されています。ご意見がありましたら、ぜひディスカッションにご参加ください。

featurePolicy.allowsFeature(feature)

  • デフォルトのオリジンでの使用が許可されている場合、true を返します。
  • 権限ポリシーと以前の機能ポリシーで設定されたポリシーの動作は同じです。
  • iframe 要素(iframeEl.featurePolicy.allowsFeature('geolocation'))で allowsFeature() が呼び出されると、戻り値には iframe に allow 属性が設定されているかどうかが反映されます。

featurePolicy.allowsFeature(feature, origin)

  • 指定されたオリジンで機能が許可されている場合は true を返します。
  • document でこのメソッドが呼び出されると、このメソッドは Feature Policy のように、指定されたオリジンで機能が許可されているかどうかを通知しなくなります。このメソッドは、そのオリジンに対して機能を許可できる可能性があることを示します。iframe に allow 属性が設定されているかどうかを追加で確認する必要があります。デベロッパーは、iframe 要素の allow 属性について追加のチェックを行い、サードパーティのオリジンでこの機能が許可されているかどうかを判断する必要があります。

element オブジェクトを使用して iframe 内の特徴を確認する

document.allowsFeature(feature, origin) とは異なり、allow 属性を考慮する element.allowsFeature(feature) を使用できます。

const someIframeEl = document.getElementById('some-iframe')
const isCameraFeatureAllowed = someIframeEl.featurePolicy.allowsFeature('camera')

featurePolicy.allowedFeatures()

  • デフォルトの送信元の使用が許可される機能のリストを返します。
  • 権限ポリシーと機能ポリシーで設定されたポリシーの動作は同じです。
  • 関連付けられているノードが iframe の場合は、allow 属性が考慮されます。

featurePolicy.features()

  • ブラウザで利用可能な機能のリストを返します。
  • 権限ポリシーと機能ポリシーで設定されたどちらのポリシーでも動作は同じ

Chrome DevTools との統合

Chrome DevTools と権限ポリシーの統合

DevTools で権限ポリシーの仕組みを確認する。

  1. Chrome DevTools を開きます
  2. [アプリケーション] パネルを開き、各フレームで許可されている機能と許可されていない機能を確認します。
  3. サイドバーで、検査するフレームを選択します。選択したフレームで使用が許可されている機能と、そのフレームでブロックされている機能のリストが表示されます。

Feature-Policy からの移行

Feature-Policy ヘッダーを使用している場合は、次の手順で権限ポリシーに移行できます。

機能ポリシー ヘッダーを権限ポリシー ヘッダーに置き換える

機能ポリシーのヘッダーは Chromium ベースのブラウザでのみサポートされており、権限ポリシーのヘッダーは Chrome 88 以降でサポートされているため、権限ポリシーを使用して既存のヘッダーを更新しても安全です。

Feature-Policy:
  autoplay *;
  geolocation 'self';
  camera 'self' 'https://trusted-site.example';
  fullscreen 'none';

機能ポリシーを使用した場合。

新規
Permissions-Policy:
  autoplay=*,
  geolocation=(self),
  camera=(self "https://trusted-site.example"),
  fullscreen=()

権限に関するポリシーを適用できるようになりました。

document.allowsFeature(feature, origin) の使用量を更新

document.allowsFeature(feature, origin) メソッドを使用して iframe で許可されている機能を確認する場合は、iframe 要素に適用されている allowsFeature(feature) メソッドを使用し、document は使用しないでください。メソッド element.allowsFeature(feature) は allow 属性を考慮しますが、document.allowsFeature(feature, origin) は考慮しません。

document で機能のアクセス権を確認する

document をベースノードとして引き続き使用するには、iframe タグの allow 属性について追加のチェックを行う必要があります。

<iframe id="some-iframe" src="https://example.com" allow="camera"></iframe>
Permissions-Policy: camera=(self "https://example.com")
const isCameraPolicySet = document.featurePolicy.allowsFeature('camera', 'https://example.com')

const someIframeEl = document.getElementById('some-iframe')
const hasCameraAttributeValue = someIframeEl.hasAttribute('allow')
&& someIframeEl.getAttribute('allow').includes('camera')

const isCameraFeatureAllowed = isCameraPolicySet && hasCameraAttributeValue

document を使用して既存のコードを更新するのではなく、前の例のように element オブジェクトで allowsFeature() を呼び出すことをおすすめします。

Reporting API

Reporting API はウェブ アプリケーション向けの一貫したレポート メカニズムを提供します。また、権限ポリシー違反の Reporting API は試験運用版機能としてご利用いただけます。

試験運用版の機能をテストする場合は、チュートリアルに沿って chrome://flags/#enable-experimental-web-platform-features でフラグを有効にしてください。このフラグを有効にすると、DevTools の [Application] タブで、権限ポリシー違反を確認できます。

次の例は、Reporting API ヘッダーの作成方法を示しています。

Reporting-Endpoints: main-endpoint="https://reports.example/main", default="https://reports.example/default"

Content-Security-Policy: script-src 'self'; object-src 'none'; report-to main-endpoint;
Document-Policy: document-write=?0; report-to=main-endpoint;

現在の実装では、前述の例のように「default」という名前のエンドポイントを構成することで、そのフレーム内で発生した違反からポリシー違反レポートを受信できます。サブフレームには、独自のレポート構成が必要です。

補足説明

権限ポリシーの詳細については、次のリソースをご覧ください。