機能ポリシーの概要

概要

フィーチャー ポリシーを使用すると、ウェブ デベロッパーはブラウザ内の特定の API とウェブ機能の動作を、選択的に有効または無効にしたり、変更したりできます。これは CSP と似ていますが、セキュリティを制御するのではなく、機能を制御します。

機能ポリシー自体は、高品質なウェブアプリの構築(および維持)という Google の目標を促進するために、デベロッパーとブラウザの間で結ばれるオプトイン契約にすぎません。

はじめに

ウェブ向けの開発は、困難な冒険です。パフォーマンスを重視し、最新のベスト プラクティスをすべて活用した優れたウェブアプリを構築するのは、それだけでも大変なことです。時間の経過とともにそのエクスペリエンスを維持することはさらに困難です。プロジェクトが進化するにつれて、開発者が参加したり、新しい機能が導入されたり、コードベースが拡大したりします。一度達成した素晴らしいエクスペリエンス TM が劣化し、UX も低下し始める可能性があります。機能ポリシーは、順調に進んでいくことを目的としています。

Feature Policy を使用すると、一連の「ポリシー」をオプトインして、サイト全体で使用される特定の機能にブラウザが適用できるようにします。これらのポリシーは、サイトがアクセスできる API を制限したり、特定の機能についてブラウザのデフォルトの動作を変更したりします。

Feature Policy でできることの例を以下に示します。

  • モバイルとサードパーティの動画に対する autoplayデフォルトの動作を変更します。
  • cameramicrophone などの機密性の高い API の使用をサイトに制限します。
  • iframe が fullscreen API を使用できるようにします。
  • 同期 XHR や document.write() などの古い API の使用をブロックします。
  • 画像のサイズが適切であり(レイアウトのスラッシングを防ぐなど)、ビューポートに対して大きすぎないこと(ユーザーの帯域幅を浪費しないなど)を確認します。

ポリシーは、デベロッパーとブラウザ間の契約です。これらは、デベロッパーの意図をブラウザに伝え、アプリが不正な動作をしようとしたときに、デベロッパーが正しい行動をとるようにします。サイトまたは埋め込まれたサードパーティのコンテンツが、デベロッパーが事前に選択したルールのいずれかに違反しようとした場合、ブラウザはより優れた UX で動作をオーバーライドするか、API 全体をブロックします。

機能ポリシーの使用

Feature Policy には、特徴を制御する 2 つの方法があります。

  1. Feature-Policy HTTP ヘッダーを介して。
  2. iframe の allow 属性。

Feature Policy を使用する最も簡単な方法は、ページのレスポンスとともに Feature-Policy HTTP ヘッダーを送信することです。このヘッダーの値は、特定のオリジンに対してブラウザが遵守するポリシーまたはポリシーのセットです。

Feature-Policy: <feature> <allow list origin(s)>

配信元の許可リストには、次のような複数の値を指定できます。

  • *: この機能は、トップレベルのブラウジング コンテキストとネストされたブラウジング コンテキスト(iframe)で使用できます。
  • 'self': この機能は、トップレベルのブラウジング コンテキストと同一オリジンのネストされたブラウジング コンテキストで許可されます。ネストされたブラウジング コンテキストのクロスオリジン ドキュメントでは、使用できません。
  • 'none': この機能は、トップレベルのブラウジング コンテキストとネストされたブラウジング コンテキストで禁止されています。
  • <origin(s)>: ポリシーを有効にする特定のオリジン(例: https://example.com)。

たとえば、サイト全体で Geolocation API を使用するすべてのコンテンツをブロックするとします。これを行うには、geolocation 機能に対して 'none' の厳格な許可リストを送信します。

Feature-Policy: geolocation 'none'

コードや iframe が Geolocation API を使用しようとすると、ブラウザによってブロックされます。これは、ユーザーが位置情報の共有を許可している場合でも同じです

設定された位置情報ポリシーに違反している
設定された位置情報ポリシーに違反している。

場合によっては、このポリシーを少し緩和した方がよいこともあります。許可リストに 'self' を設定すると、独自のオリジンが Geolocation API を使用できるようにし、サードパーティ コンテンツが Geolocation API にアクセスできないようにできます。

Feature-Policy: geolocation 'self'

iframe の allow 属性

Feature Policy を使用する 2 つ目の方法は、iframe 内のコンテンツを制御することです。埋め込みコンテンツのポリシーリストを指定するには、allow 属性を使用します。

<!-- Allow all browsing contexts within this iframe to use fullscreen. -->
<iframe src="https://example.com..." allow="fullscreen"></iframe>

<!-- Equivalent to: -->
<iframe src="https://example.com..." allow="fullscreen *"></iframe>

<!-- Allow only iframe content on a particular origin to access the user's location. -->
<iframe
  src="https://another-example.com/demos/..."
  allow="geolocation https://another-example.com"
></iframe>

既存の iframe 属性はどうなりますか?

Feature Policy によって制御される機能の一部には、動作を制御する既存の属性があります。たとえば、<iframe allowfullscreen> は、iframe コンテンツが HTMLElement.requestFullscreen() API を使用できるようにする属性です。また、Payment Request APIgetUserMedia() を許可する allowpaymentrequest 属性と allowusermedia 属性もあります。

可能であれば、これらの古い属性ではなく allow 属性を使用してください。下位互換性をサポートする必要がある場合は、同等のレガシー属性(<iframe allowfullscreen allow="fullscreen"> など)で allow 属性を使用できます。ただし、より制限の厳しいポリシーが優先されます。たとえば、allow="fullscreen 'none'"allowfullscreen よりも制限が厳しいため、次の iframe はフルスクリーンに移行できません。

<!-- Blocks fullscreen access if the browser supports feature policy. -->
<iframe allowfullscreen allow="fullscreen 'none'" src="..."></iframe>

複数のポリシーを一度に制御する

ポリシー ディレクティブのリスト(; で区切る)を含む HTTP ヘッダーを送信することで、複数の機能を同時に制御できます。

Feature-Policy: unsized-media 'none'; geolocation 'self' https://example.com; camera *;

または、ポリシーごとに個別のヘッダーを送信します。

Feature-Policy: unsized-media 'none'
Feature-Policy: geolocation 'self' https://example.com
Feature-Policy: camera *;

この例では、次のことを行います。

  • すべてのブラウジング コンテキストで unsized-media の使用を禁止します。
  • ページ自体のオリジンと https://example.com を除くすべてのブラウジング コンテキストで geolocation の使用を禁止します。
  • すべてのブラウジング コンテキストで camera へのアクセスを許可します。

- iframe に複数のポリシーを設定する

<!-- Blocks the iframe from using the camera and microphone
     (if the browser supports feature policy). -->
<iframe allow="camera 'none'; microphone 'none'"></iframe>

JavaScript API

Chrome 60 では Feature-Policy HTTP ヘッダーと iframe の allow 属性のサポートが追加されましたが、JavaScript API は Chrome 74 で追加されました。

この API を使用すると、クライアントサイドのコードでページ、フレーム、またはブラウザで許可されている機能を特定できます。この機能には、メイン ドキュメントの場合は document.featurePolicy、iframe の場合は frame.featurePolicy からアクセスできます。

次の例は、サイト https://example.comFeature-Policy: geolocation 'self' のポリシーを送信した場合の結果を示しています。

/* @return {Array<string>} List of feature policies allowed by the page. */
document.featurePolicy.allowedFeatures();
// → ["geolocation", "midi",  "camera", "usb", "autoplay",...]

/* @return {boolean} True if the page allows the 'geolocation' feature. */
document.featurePolicy.allowsFeature('geolocation');
// → true

/* @return {boolean} True if the provided origin allows the 'geolocation' feature. */
document.featurePolicy.allowsFeature(
  'geolocation',
  'https://another-example.com/'
);
// → false

/* @return {Array<string>} List of feature policies allowed by the browser
regardless of whether they are in force. */
document.featurePolicy.features();
// → ["geolocation", "midi",  "camera", "usb", "autoplay",...]

/* @return {Array<string>} List of origins (used throughout the page) that are
   allowed to use the 'geolocation' feature. */
document.featurePolicy.getAllowlistForFeature('geolocation');
// → ["https://example.com"]

ポリシーのリスト

Feature Policy で制御できる機能はどのようなものですか?

現時点では、実装されるポリシーとその使用方法に関するドキュメントはありません。また、さまざまなブラウザが仕様を採用し、さまざまなポリシーを実装するにつれて、このリストは時間の経過とともに増えていきます。特徴ポリシーは動的なターゲットとなるため、優れたリファレンス ドキュメントが不可欠です。

現時点では、制御可能な機能を確認する方法はいくつかあります。

  • デモの機能ポリシーのキッチンシンクをご覧ください。Blink に実装されている各ポリシーの例が含まれています。
  • 特徴名の一覧については、Chrome のソースをご覧ください。
  • about:blank に対して document.featurePolicy.allowedFeatures() に対してクエリを実行し、リストを見つけます。
        ["geolocation",
         "midi",
         "camera",
         "usb",
         "magnetometer",
         "fullscreen",
         "animations",
         "payment",
         "picture-in-picture",
         "accelerometer",
         "vr",
        ...
  • Blink で実装されているポリシーや検討中のポリシーについては、chromestatus.com をご覧ください。

これらのポリシーの使用方法については、仕様の GitHub リポジトリをご覧ください。ポリシーの一部について説明しています。

よくある質問

機能ポリシーはどのような場合に使用すればよいですか?

すべてのポリシーはオプトインであるため、適切なタイミングと場所で Feature Policy を使用してください。たとえば、アプリが画像ギャラリーである場合、maximum-downscaling-image ポリシーを使用すると、巨大な画像をモバイル ビューポートに送信しないようにできます。

document-writesync-xhr などの他のポリシーは、慎重に使用する必要があります。オンにすると、広告などのサードパーティ コンテンツが機能しなくなる可能性があります。一方、機能ポリシーは、ページでこれらの危険な API が使用されていないことを確認するための簡単なチェックとして使用できます。

機能ポリシーは開発環境と本番環境のどちらで使用できますか?

両方です。開発中はポリシーを有効にし、本番環境ではポリシーを有効にしておくことをおすすめします。開発中にポリシーを有効にすると、適切な方向に進むことができます。予期せぬ回帰を発生前に検出できます。ユーザーに対して特定の UX を保証するには、本番環境でポリシーを有効にします。

ポリシー違反をサーバーに報告する方法はありますか?

Reporting API準備中ですCSP 違反非推奨に関するレポートの受信をサイトがオプトインする方法と同様に、機能のポリシー違反に関するレポートを実際に受け取ることができます。

iframe コンテンツの継承ルールは何ですか?

スクリプト(ファーストパーティまたはサードパーティ)は、ブラウジング コンテキストのポリシーを継承します。つまり、トップレベルのスクリプトはメイン ドキュメントのポリシーを継承します。

iframe は親ページのポリシーを継承します。iframeallow 属性がある場合、親ページと allow リストの間でより厳しいポリシーが優先されます。iframe の使用方法については、iframe の allow 属性をご覧ください。

いいえ。ポリシーの存続期間は 1 つのページ ナビゲーション レスポンスです。ユーザーが新しいページに移動した場合、ポリシーを適用するには、新しいレスポンスで Feature-Policy ヘッダーを明示的に送信する必要があります。

機能ポリシーに対応しているブラウザを教えてください。

ブラウザのサポートに関する最新情報については、caniuse.com をご覧ください。

現在、機能ポリシーをサポートしているのは Chrome のみです。ただし、API サーフェス全体がオプトインまたは機能検出が可能なため、機能ポリシーによって段階的な機能強化が実現します

まとめ

機能ポリシーは、UX の向上とパフォーマンスの向上につながる明確な道筋を示すのに役立ちます。フットガンの可能性をコードベースに侵入する前に回避できるため、アプリの開発やメンテナンスで特に便利です。

その他のリソース: