許可權策略

實驗性: 這是一項實驗性技術
在生產中使用此技術之前,請仔細檢查瀏覽器相容性表格

許可權策略為 Web 開發者提供了明確宣告網站上哪些功能可以使用、哪些功能不能使用的機制。你可以定義一組“策略”,以限制網站程式碼可以訪問哪些 API 或修改瀏覽器對某些功能的預設行為。這使得你即使在程式碼庫不斷演進的情況下,也能強制執行最佳實踐,並更安全地整合第三方內容。

許可權策略類似於內容安全策略,但它控制的是功能而不是安全行為。

許可權策略的應用示例

  • 更改移動端和第三方影片自動播放的預設行為。
  • 限制網站使用攝像頭、麥克風或揚聲器等敏感裝置。
  • 允許 iframe 使用全屏 API
  • 為了提高效能,阻止不在視口中可見的專案被指令碼化。

注意:許可權策略曾被稱為功能策略。名稱已更改,HTTP 頭語法也已更改,因此如果您過去使用過功能策略,請牢記這一點並檢視瀏覽器支援表格。<iframe allow=" ... "> 語法保持不變。

概念與用法

Web 提供了可能存在隱私或安全風險的功能和 API,如果這些功能被濫用。在這種情況下,你可能希望嚴格限制網站上功能的使用方式。在每種情況下,Web 開發者都應該有一種直觀或不破壞性的方式來檢測和處理功能被停用情況。

一些方法包括

  • 需要使用者授予許可權的 JavaScript API 返回“許可權被拒絕”。
  • 提供功能訪問的 JavaScript API 返回 false 值或丟擲錯誤。
  • API 甚至不被暴露,就像它們不存在一樣。
  • 控制功能行為的選項具有不同的預設值。

注意:新引入的功能可能具有明確的 API 來表示狀態。稍後與許可權策略整合的現有功能通常會使用現有機制。

許可權策略允許您控制哪些源可以在頂級頁面和嵌入的<iframe><iframe>使用哪些功能。其目的是強制執行良好使用者體驗的最佳實踐,並提供對敏感強大功能(即使用者在相關程式碼執行前必須明確同意使用這些功能)的細粒度控制。

許可權策略提供了兩種指定策略的方式

這些是相互獨立但又相互關聯的——有關詳細資訊,請參閱嵌入內容的策略繼承

注意:指令碼可以透過位於Document.featurePolicyHTMLIFrameElement.featurePolicyFeaturePolicy物件以程式設計方式查詢許可權策略資訊。

要控制每個功能,您需要編寫一個包含以下內容的策略

  • 一個指令,用於標識要控制的功能的名稱。請參閱可用指令列表
  • 一個允許列表,它是應該控制該功能的來源列表。您可以為所有或特定來源啟用該功能,或阻止其在所有來源中使用。

請參閱下面的多個示例。

與許可權 API 的關係

許可權策略和許可權 API 密切相關,但有所不同。這些技術控制的許可權功能有所重疊。

  • 許可權策略允許伺服器設定是否可以在特定文件(或其中嵌入的<frame>)中使用某個功能。這些功能被稱為策略控制功能——請參閱許可權策略指令列表
  • 許可權 API 根據使用者授予的許可權來控制對功能的訪問。這些功能記錄在許可權登錄檔中。

兩種技術中用於標識每個功能的字串保持一致,例如,地理定位 APIgeolocation。許可權登錄檔中的大多數 API 功能也都有相應的許可權策略指令。一個例外是通知 API

通常,當權限策略阻止使用強大功能時,甚至不會向用戶請求使用該功能的許可權,並且許可權 API 的query()方法將返回state值為denied

另請參閱許可權 > 與許可權策略規範的關係

允許列表

允許列表是一個來源列表,包含一個或多個以下括號內的值,用空格分隔

  • *:此文件以及所有巢狀瀏覽上下文(<iframe>)都將允許該功能,無論其來源如何。
  • () (空允許列表):該功能在頂級和巢狀瀏覽上下文中被停用。<iframe> allow 屬性的等效值是 'none'
  • self:此文件以及所有同源的巢狀瀏覽上下文(<iframe>)中都將允許該功能。該功能在巢狀瀏覽上下文中的跨源文件中不允許。self 可以被視為 https://your-site.example.com 的簡寫。<iframe> allow 屬性的等效值是 'self'
  • 'src':只要載入到此<iframe>中的文件與其src屬性中的 URL 來自同一源,則允許在該<iframe>中使用該功能。此值僅在<iframe> allow屬性中使用,並且是<iframe>中的預設允許列表值。
  • "<origin>":該功能允許用於特定來源(例如,"https://a.example.com")。來源應以空格分隔。請注意,<iframe> allow 屬性中的來源無需加引號。

*() 只能單獨使用,而 selfsrc 可以與一個或多個來源組合使用。

注意:指令有一個預設允許列表,對於Permissions-Policy HTTP 頭,它始終是*selfnone之一,如果未在策略中明確列出,則控制預設行為。這些在單獨的指令參考頁面上指定。對於<iframe> allow屬性,預設行為始終是src

在支援的情況下,您可以在許可權策略源中包含萬用字元。這意味著您不必在允許列表中明確指定多個不同的子域,而可以使用萬用字元在一個源中指定它們全部。

因此,不是這樣

http
("https://example.com" "https://a.example.com" "https://b.example.com" "https://c.example.com")

您可以指定

http
("https://example.com" "https://*.example.com")

注意: "https://*.example.com" 不匹配 "https://example.example.com"

允許列表示例

  • *
  • ()
  • (self)
  • (src)
  • ("https://a.example.com")
  • ("https://a.example.com" "https://b.example.com")
  • (self "https://a.example.com" "https://b.example.com")
  • (src "https://a.example.com" "https://b.example.com")
  • ("https://*.example.com")

Permissions-Policy 頭語法

通用語法如下所示

http
Permissions-Policy: <directive>=<allowlist>

因此,例如要阻止所有對地理位置的訪問,您將這樣做

http
Permissions-Policy: geolocation=()

或者要允許訪問部分源,您可以這樣做

http
Permissions-Policy: geolocation=(self "https://a.example.com" "https://b.example.com")

可以透過傳送帶有逗號分隔策略列表的標頭檔案,或者為每個策略傳送單獨的標頭檔案,來同時控制多個功能。

例如,以下是等效的

http
Permissions-Policy: picture-in-picture=(), geolocation=(self "https://example.com"), camera=*;

Permissions-Policy: picture-in-picture=()
Permissions-Policy: geolocation=(self "https://example.com")
Permissions-Policy: camera=*

嵌入式框架語法

為了使<iframe>啟用某項功能,其允許的源也必須在父頁面的允許列表中。由於這種繼承行為,建議在 HTTP 頭中指定對某項功能最廣泛可接受的支援,然後在每個<iframe>中指定所需的子集支援。

通用語法如下所示

html
<iframe src="<origin>" allow="<directive> <allowlist>"></iframe>

因此,例如要阻止所有對地理位置的訪問,您將這樣做

html
<iframe src="https://example.com" allow="geolocation 'none'"></iframe>

要將策略應用於當前源和其他源,您可以這樣做

html
<iframe
  src="https://example.com"
  allow="geolocation 'self' https://a.example.com https://b.example.com"></iframe>

這很重要:預設情況下,如果一個 <iframe> 導航到另一個源,該策略不會應用於 <iframe> 導航到的源。透過在 allow 屬性中列出 <iframe> 導航到的源,應用於原始 <iframe> 的許可權策略將應用於 <iframe> 導航到的源。

透過在 allow 屬性中包含以分號分隔的策略指令列表,可以同時控制多個功能。

html
<iframe
  src="https://example.com"
  allow="geolocation 'self' https://a.example.com https://b.example.com; fullscreen 'none'"></iframe>

src值值得特別提一下。我們上面提到,使用此允許列表值意味著只要載入到此<iframe>中的文件與其src屬性中的 URL 來自同一源,則允許在此<iframe>中使用相關功能。此值是allow中列出的功能的預設 allowlist值,因此以下兩者是等效的

html
<iframe src="https://example.com" allow="geolocation 'src'">
  <iframe src="https://example.com" allow="geolocation"></iframe
></iframe>

注意:如您所見,<iframe> 策略的語法與 Permissions-Policy 頭的語法略有不同。前者仍然使用舊版功能策略規範的相同語法,該規範已被許可權策略取代。

圍欄框架和許可權策略

<fencedframe> 與許可權策略的互動方式與 <iframe> 相同,但限制得多。只有設計用於 <fencedframe> 的特定功能才能透過為其設定的許可權策略啟用;其他策略控制的功能在此上下文中不可用。

有關詳細資訊,請參閱適用於圍欄框架的許可權策略

嵌入式內容的策略繼承

指令碼繼承其瀏覽上下文的策略,無論其來源如何。這意味著頂級指令碼繼承主文件的策略。

所有 <iframe> 都繼承其父頁面的策略。如果 <iframe> 具有 allow 屬性,並且父頁面具有 Permissions-Policy,則父頁面和 allow 屬性的策略將合併,並採用最嚴格的子集。為了使 <iframe> 啟用某個功能,該源必須同時在父頁面和 allow 屬性的允許列表中。

在策略中停用功能是一次性開關。如果父框架為子框架停用了某個功能,則子框架無法重新啟用它,子框架的任何後代也無法重新啟用它。

示例

HTTP 頭和<iframe>策略的結合

例如,假設我們想在自己的源和來自我們信任的廣告網路中的嵌入內容中啟用地理位置使用。我們可以這樣設定頁面範圍的許可權策略

http
Permissions-Policy: geolocation=(self "https://trusted-ad-network.com")

在我們的廣告 <iframe> 中,我們可以這樣設定對 https://trusted-ad-network.com 源的訪問許可權

html
<iframe src="https://trusted-ad-network.com" allow="geolocation"></iframe>

如果不同的源最終被載入到<iframe>中,它將無法訪問地理位置

html
<iframe src="https://rogue-origin-example.com" allow="geolocation"></iframe>

規範

規範
許可權策略
# permissions-policy-http-header-field

瀏覽器相容性

另見