使用權限政策控管瀏覽器功能

管理網頁和第三方 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 屬性合併

運用功能政策,您可以將來源新增至標頭來源清單,或是在 iframe 標記中加入 allow 屬性,將功能新增至跨來源頁框。使用權限政策時,如果您將跨來源頁框加入來源清單,該來源的 iframe 標記必須包含 allow 屬性。 如果回應不含權限政策標頭,系統會將來源清單視為含有預設值 *。在 iframe 中新增 allow 屬性後,使用者即可使用這項功能。

因此,建議開發人員在回應中明確設定「權限政策」標頭,如此一來,即使來源清單中未列出的跨來源 iframe,也無法使用這項功能 (即使 allow 已存在)。

在 Chrome 第 88 版之後,仍可使用功能政策,但這會成為權限政策的別名。除語法外,邏輯沒有差異。如果同時使用權限政策和功能政策標頭,系統會提高 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")

以及將 allow 屬性明確設為信任網站的 iframe 標記:

<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. 假如 iframe 是透過另一個子網域 (subdomain.your-site-example) 放送,但這些子網域未加入來源清單,但 iframe 代碼已設定 allow 屬性,則可能無法使用這項功能。系統會將不同的子網域視為同網站但跨來源。
  4. 這個跨來源 iframe (trusted-site.example) 已新增至來源清單,並在 iframe 標記上設定 allow 屬性,如此即可使用此功能。
  5. 如果來源清單中加入的跨來源 iframe (trusted-site.example) 不含 allow 屬性,則無法使用這項功能。
  6. 即使 iframe 代碼包含 allow 屬性,未加入來源清單的跨來源 iframe (ad.example) 也無法使用這項功能。

Permissions-Policy HTTP 回應標頭

使用者提出要求,伺服器會以權限政策標頭回應,然後瀏覽器根據該標頭授予存取權。

Permissions-Policy: &lt;feature&gt;=(&lt;token&gt;|&lt;origin(s)&gt;)

在伺服器的回應中使用 Permissions-Policy 標頭,即可設定功能的允許來源。標頭值可以使用符記和來源字串的組合。所有來源的可用權杖都是 *,而相同來源的 self 則是 self

如果標頭適用於多項地圖項目,請以半形逗號分隔每個地圖項目。如果列出多個來源,請在來源清單中使用空格分隔每個來源。標頭會列出來自跨來源要求的來源,iframe 標記必須包含 allow 屬性。

以下提供幾個鍵/值組合範例:

  • 語法:[FEATURE]=*
    • 已套用至所有來源的政策
    • 範例:geolocation=*
  • 語法:[FEATURE]=(self)
    • 適用於相同來源的政策
    • 範例:geolocation=(self)
  • 語法:[FEATURE]=(self [ORIGIN(s)])
    • 套用至相同來源和指定來源的政策
    • 範例:geolocation=(self "https://a.example" "https://b.example")
    • self」是https://your-site.example的簡寫
  • 語法:[FEATURE]=([ORIGIN(s)])
    • 套用至相同來源和指定來源的政策
    • 範例:geolocation=("https://your-site.example" "https://a.example" "https://b.example")
    • 使用這個語法時,其中一個來源應為嵌入程式的來源。如果嵌入程式頁面本身未授予權限,則即使網頁內嵌的 iframe 已新增至來源清單,系統仍會封鎖該 iframe (因為權限政策已委派權限)。您也可以使用 self 權杖。
  • 語法:[FEATURE]=()
    • 禁止所有來源使用這項功能
    • 範例:geolocation=()

不同的子網域和路徑

系統會將不同的子網域 (例如 https://your-site.examplehttps://subdomain.your-site.example) 視為同網站但跨來源。因此,即使在來源清單中新增子網域,也無法存取同一個網站的其他子網域。凡是想要使用這項功能的嵌入式子網域,都必須分別加到來源清單中。舉例來說,如果使用者的瀏覽主題只能存取標題為 Permissions-Policy: browsing-topics=(self) 的相同來源,則來自相同網站不同子網域的 iframe,https://subdomain.your-site.example 將無法存取主題。

系統會將不同的路徑 (例如 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 導覽的目標來源。只要在 allow 屬性中列出 iframe 前往的來源,系統就會對 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.example (self) 能存取地理位置。如果只想在您的網頁上使用這項功能,請使用以下語法。

您可以在示範中查看這項設定。

可在相同來源和特定跨來源上使用的功能

允許存取這項功能的指定來源架構

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

這個語法允許將地理位置同時用於自身 (https://your-site.example) 和 https://trusted-site.example。請記得在 iframe 代碼中明確加入 allow 屬性。如果另一個 iframe 包含 <iframe src="https://ad.example" allow="geolocation">https://ad.example 將無法使用地理位置功能。只有原始網頁和 https://trusted-site.example 列在來源清單中,且 iframe 標記中也包含 allow 屬性,才能存取使用者的功能。

您可以在示範中查看這項設定。

在所有來源中遭到封鎖

禁止存取功能的所有來源架構

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, 來源)

  • 如果這項功能允許指定起點使用,則傳回 true
  • 如果在 document 上呼叫此方法,此方法將不會再指出這項功能是否適用於指定來源,例如功能政策。現在,這個方法會告知您該功能可以允許該來源存取。請務必額外檢查 iframe 是否已設定 allow 屬性。開發人員必須針對 iframe 元素上的 allow 屬性進行額外檢查,判斷是否允許第三方來源使用這項功能。

使用 element 物件檢查 iframe 中的功能

您可以使用允許屬性的 element.allowsFeature(feature),這與不考慮不允許屬性的 document.allowsFeature(feature, origin) 不同。

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

featurePolicy.allowedFeatures()

  • 傳回可用於預設來源用途的功能清單。
  • 權限政策和功能政策設定的政策行為相同
  • 當關聯節點是 iframe 時,系統會將 allow 屬性納入考量。

featurePolicy.features()

  • 傳回瀏覽器中可用的功能清單。
  • 權限政策和功能政策設定的政策行為相同

Chrome 開發人員工具整合

Chrome 開發人員工具整合權限政策

瞭解權限政策在開發人員工具中的運作方式。

  1. 開啟 Chrome 開發人員工具
  2. 開啟「應用程式」面板,查看每個頁框允許的功能和禁止的功能。
  3. 在側欄中,選取要檢查的頁框。系統會列出所選影格可使用的功能,以及該影格中遭封鎖的功能清單。

從功能政策遷移

如果您目前使用 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) 方法,而非包含 documentelement.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 中啟用標記。啟用旗標後,您就可以在開發人員工具的「應用程式」分頁下觀察違反權限政策的情形:

以下範例說明如何建構 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」的端點,就能收到該頁框中所有違規事件的報告。子頁框需要專屬的報表設定。

瞭解詳情

如要進一步瞭解權限政策,請參閱下列資源: