概要
機能ポリシーを使用すると、ウェブ デベロッパーはブラウザ内の特定の API とウェブ機能の動作を選択的に有効、無効、変更できます。CSP に似ていますが、セキュリティを制御するのではなく、機能を制御します。
機能ポリシー自体は、高品質なウェブアプリの構築(および維持)という Google の目標を促進するために、デベロッパーとブラウザの間で結ばれるオプトイン契約にすぎません。
はじめに
ウェブ向けの開発は、困難な冒険です。パフォーマンスを重視し、最新のベスト プラクティスをすべて活用した優れたウェブアプリを構築するのは、それだけでも大変な作業です。時間の経過とともにそのエクスペリエンスを維持することはさらに困難です。プロジェクトが進化するにつれて、開発者が参加したり、新機能が導入されたり、コードベースが拡大したりします。一度達成した「優れたエクスペリエンス」が低下し始め、UX が損なわれる可能性があります。機能ポリシーは、目標達成をサポートするように設計されています。
Feature Policy を使用すると、一連の「ポリシー」をオプトインして、サイト全体で使用される特定の機能にブラウザが適用できるようにします。これらのポリシーは、サイトがアクセスできる API を制限したり、特定の機能についてブラウザのデフォルトの動作を変更したりします。
Feature Policy でできることの例を以下に示します。
- モバイルとサードパーティの動画で
autoplayのデフォルトの動作を変更。 cameraやmicrophoneなどの機密性の高い API の使用をサイトに制限します。- iframe が
fullscreenAPI を使用できるようにします。 - 同期 XHR や
document.write()などの古い API の使用をブロックします。 - 画像のサイズが適切であり(例: レイアウトのスラッシングを防ぐ)、ビューポートに対して大きすぎないこと(例: ユーザーの帯域幅を浪費する)を確認します。
ポリシーは、デベロッパーとブラウザ間の契約です。これらは、デベロッパーの意図をブラウザに通知し、アプリが不正な動作をしようとしたときに、不正行為を防ぐのに役立ちます。サイトまたは埋め込まれたサードパーティ コンテンツが、デベロッパーが事前に選択したルールに違反しようとすると、ブラウザは UX を改善するために動作をオーバーライドするか、API を完全にブロックします。
機能ポリシーの使用
Feature Policy には、特徴を制御する 2 つの方法があります。
Feature-PolicyHTTP ヘッダーを介して。- iframe の
allow属性。
Feature-Policy HTTP ヘッダー
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 API と getUserMedia() を許可する 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.com に Feature-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-write や sync-xhr などの他のポリシーは、慎重に使用する必要があります。オンにすると、広告などのサードパーティ コンテンツが機能しなくなる可能性があります。一方、機能ポリシーは、ページでこれらの危険な API が使用されていないことを確認するための簡単なチェックとして使用できます。
Feature Policy は開発環境と本番環境のどちらで使用すればよいですか?
両方です。開発中はポリシーを有効にし、本番環境ではポリシーを有効にしておくことをお勧めします。開発中にポリシーを有効にすると、適切な方向で開発を開始できます。予期しないリグレッションを発生前に検出できます。本番環境でポリシーをオンにして、ユーザーに一定の UX を保証します。
ポリシー違反をサーバーに報告する方法はありますか?
Reporting API は現在開発中です。サイトが CSP 違反や非推奨に関するレポートの受信を有効にできる場合と同様に、フィーチャー ポリシー違反に関するレポートを受け取ることができます。
iframe コンテンツの継承ルールは何ですか?
スクリプト(ファーストパーティまたはサードパーティ)は、ブラウジング コンテキストのポリシーを継承します。つまり、最上位のスクリプトはメイン ドキュメントのポリシーを継承します。
iframe は親ページのポリシーを継承します。iframe に allow 属性がある場合、親ページと allow リストの間でより厳しいポリシーが優先されます。iframe の使用方法については、iframe の allow 属性をご覧ください。
ポリシーを適用すると、ページの移動後も適用されますか?
いいえ。ポリシーの有効期間は、1 ページのナビゲーション レスポンスです。ユーザーが新しいページに移動した場合、ポリシーを適用するには、新しいレスポンスで Feature-Policy ヘッダーを明示的に送信する必要があります。
どのブラウザが Feature Policy に対応していますか?
ブラウザのサポートに関する最新情報については、caniuse.com をご覧ください。
現在、機能ポリシーをサポートしているのは Chrome のみです。ただし、API サーフェス全体がオプトインまたは機能検出可能であるため、機能ポリシーはプログレッシブ エンハンスに適しています。
まとめ
機能ポリシーは、UX の向上とパフォーマンスの向上につながる明確な道筋を示すのに役立ちます。潜在的なフットガンがコードベースに侵入する前に回避できるため、アプリの開発やメンテナンス時に特に便利です。
その他のリソース:
- 機能に関するポリシーの説明
- 特徴ポリシーの仕様
- キッチンシンクのデモ
- 機能ポリシーの DevTools 拡張機能 - ページで機能ポリシーを試すためのテスター。
- chromestatus.com のエントリ