使用功能策略保護您的網站
已發表: 2022-03-10在最近的 Chrome 開發者峰會上強調的 Web 平台功能之一是功能政策,其目的是“允許網站作者有選擇地啟用和禁用各種瀏覽器功能和 API 的使用”。 在本文中,我將通過一些實際示例來看看這對 Web 開發人員意味著什麼。
在 Google Developers 網站上的介紹性文章中,Eric Bidelman 將功能政策描述如下:
“功能政策本身是開發人員和瀏覽器之間的一些選擇加入協議,可以幫助我們實現構建(和維護)高質量網絡應用程序的目標。”
該規範由 Google 開發,作為 Web Platform Incubator Group 活動的一部分。 功能政策的目的是讓我們作為 Web 開發人員能夠明確地向瀏覽器說明我們對 Web 平台功能的使用。 通過這樣做,我們就使用或不使用此特定功能達成協議。 基於此,瀏覽器可以採取行動阻止某些功能,或者向我們報告它不希望看到的功能正在被使用。
示例可能包括:
- 我正在嵌入 iframe,但我不希望嵌入的網站能夠訪問訪問者的攝像頭;
- 我想捕捉通過 CMS 將未優化圖像部署到我的站點的情況;
- 我的項目有很多開發人員,我想知道他們是否使用過時的 API,例如
document.write
。
所有這些事情都可以作為功能政策的一部分進行跟踪、阻止或報告。
如何使用功能策略
為了使用功能策略,瀏覽器需要知道兩件事:您正在為哪個功能創建策略,以及您希望如何處理該功能。
Feature-Policy: <directive> <allowlist>
<directive>
是您設置策略的功能的名稱。
當前的功能列表(來自 Chrome 開發者峰會上的演示文稿)如下:
- 加速度計
- 環境光傳感器
- 自動播放
- 相機
- 寫文件
- 加密媒體
- 全屏
- 地理位置
- 陀螺儀
- 佈局動畫
- 懶加載
- 傳統圖像格式
- 磁力計
- 迷笛
- 超大圖像
- 支付
- 畫中畫
- 揚聲器
- 同步腳本
- 同步 xhr
- 未優化的圖像
- 無尺寸媒體
- USB
- 垂直滾動
- 虛擬現實
<allowlist>
詳細說明瞭如何使用該功能 - 如果有的話 - 並採用以下一個或多個值。
-
*
最自由的政策,聲明該功能將被允許在本文檔中,以及來自此域或其他地方的任何 iframe。 例如,只能用作單個值,因為啟用所有內容並傳入域列表是沒有意義的。 -
self
該功能將在文檔和任何 iframe 中可用,但是 iframe 必須具有相同的來源。 -
src
僅在使用 iframeallow
屬性時適用。 只要加載到其中的文檔來自與 iframe 的 src 屬性中的 URL 相同的來源,這就允許使用功能。 -
none
禁用文檔和任何嵌套 iframe 的功能。 只能用作單個值。 -
<origin(s)>
該功能允許用於特定來源; 這意味著您可以指定允許該功能的域列表。 域列表以空格分隔。
您可以通過兩種方法在您的站點上啟用功能策略:您可以發送 HTTP 標頭,或在 iframe 上使用allow
屬性。
HTTP 標頭
發送 HTTP 標頭意味著您可以為設置該標頭的頁面或整個站點啟用功能策略,以及嵌入站點中的任何內容。 可以在 Web 服務器上為您的整個站點設置標頭,也可以從您的應用程序發送標頭。
例如,如果我想阻止使用地理定位 API 並且我正在使用 NGINX Web 服務器,我可以在 NGINX 中編輯我的站點的配置文件以添加以下標頭,這將阻止我站點中的任何文檔和任何使用地理定位 API 嵌入的 iframe。
add_header Feature-Policy "geolocation none;";
可以在單個標頭中設置多個策略。 為了防止地理定位和振動,但允許來自域example.com的unsized-media
,我可以設置以下內容:
add_header Feature-Policy "vibrate none; geolocation none; unsized-media https://example.com;";
iFrame 上的allow
屬性
如果我們主要關心 iframe 中的內容會發生什麼,我們可以在 iframe 本身上使用 Feature Policy; 這得益於在撰寫本文時 Chrome 和 Safari 支持這種使用的瀏覽器支持稍好一些。
如果我正在嵌入一個站點並且不希望該站點使用地理定位、攝像頭或麥克風 API,那麼我的 iframe 將類似於以下示例:
<iframe allow="geolocation 'none'; camera 'none'; microphone 'none'">
您可能已經熟悉控制 iframe 內容的各個屬性allowfullscreen
、 allowpaymentrequest
和allowusermedia
。 這些可以由功能策略allow
屬性替換,並且出於瀏覽器兼容性的原因,您可以在 iframe 上同時使用它們。 如果您確實使用了這兩個屬性,那麼將應用最嚴格的一個。 Google 文章顯示了一個使用allowfullscreen
的 iframe 示例——這意味著 iframe 被允許進入全屏,但隨後出現了與fullscreen none
相衝突的功能策略。 這些衝突,所以最嚴格的策略獲勝,這個 iframe 將不允許進入全屏。

<iframe allowfullscreen allow="fullscreen 'none'" src="...">
iframe 元素還有一個sandbox
屬性,旨在管理對許多功能的支持。 此功能還添加到內容安全策略中,其sandbox
值禁用所有沙箱功能,然後可以有選擇地重新啟用。 沙盒特性和特性策略控制的特性之間存在一些交叉,特性策略並不試圖複製沙盒已經覆蓋的那些值。 但是,它確實通過採用更細粒度的方法來管理這些策略,而不是將所有東西作為一個大型策略集在全局範圍內關閉,從而解決了沙盒的一些限制。
功能政策和報告 API
可以通過報告 API 報告違反功能政策的行為,這意味著您可以製定一套全面的政策來跟踪整個網站的功能使用情況。 這對您的用戶來說是完全透明的,但會為您提供有關如何使用功能的大量信息。
瀏覽器對功能策略的支持
目前,瀏覽器對功能策略的支持僅限於 Chrome,但是,在許多情況下,您在開發期間使用功能策略和預覽站點時,這不一定是問題。
我將在下面概述的許多用例現在都可以使用,不會對使用沒有支持的瀏覽器的網站訪問者造成任何影響。
何時使用功能策略
我真的很喜歡能夠使用功能策略來幫助支持開發網站時做出的決策的想法。 決策很可能寫在績效預算等文件中,或作為 GDPR 審計的一部分,但隨後成為我們必須記住的東西,以在網站的整個生命週期中保留。 當多人在一個站點上工作時,這並不總是那麼容易。 在最初的決策過程中可能沒有參與的人,或者可能根本不知道這些要求。 我們對第三方設法以某種方式影響我們的網站進行了很多思考,但是,有時我們的網站需要保護自己!
密切關注第三方
您可以使用 iframe 上具有allow
屬性的功能策略來阻止第三方站點訪問攝像頭或麥克風。 如果嵌入該站點的原因與這些功能無關,那麼禁用它們意味著該站點永遠無法開始要求這些功能。 然後可以將其與確保 GDPR 合規性的流程相關聯。 當您審核您的網站對隱私的影響時,您可以通過功能策略構建用於鎖定第三方訪問的流程——為您和您的訪問者提供額外的安全性和安心。
這種使用確實依賴於瀏覽器對功能策略的支持來阻止使用。 但是,如果第三方更改了他們將要執行的操作,您可以使用功能策略報告模式來通知您這些 API 的使用情況。 這會給你一個非常快速的提示——基本上只要第一個使用 Chrome 的人點擊該網站。
選擇性啟用功能
我們還可能希望有選擇地啟用一些通常被阻止的功能。 也許我們希望允許 iframe 從另一個站點加載內容以使用瀏覽器中的地理定位功能。 默認情況下,Chrome 會阻止此操作,但如果您從受信任的站點加載內容,則可以使用功能策略啟用跨域請求。 這意味著您可以在從您控制的另一個域加載內容時安全地打開功能。
發現使用過時的 API 和性能不佳的功能
功能策略可以在僅報告模式下運行。 然後它可以跟踪某些功能的使用情況,並在網站上找到它們時通知您。 這在許多情況下都很有用。 如果您有一個包含大量遺留代碼的非常大的站點,啟用功能策略將幫助您找到需要注意的地方。 如果您與大型團隊合作(尤其是如果開發人員經常引入一些第三方代碼庫),功能策略可以捕捉到您不想在網站上看到的內容。
處理優化不佳的圖像
雖然我看到的大多數關於功能策略的文章都集中在安全和隱私方面,但圍繞圖像優化的功能確實吸引了我,因為我處理了大量由技術和非技術用戶生成的內容。 功能策略可用於通過防止訪問者下載過大或未優化的圖像來幫助保護用戶體驗和網站性能。
在理想的世界中,您的 CMS 將處理圖像管理,確保圖像的大小經過合理調整,針對 Web 和它們將顯示的上下文進行了優化。然而,現實生活很少是理想的世界,因此有時調整大小的工作優化圖像留給內容編輯人員,以確保他們不會將巨大的圖像上傳到網絡。 如果您使用的是上面沒有內容管理層的靜態 CMS,這尤其是一個問題。 即使是技術人員,也很容易忘記調整作為佔位符彈出到文件夾中的巨大屏幕截圖或相機圖像的大小。
目前在 Chrome 中的標誌後面是可以提供幫助的功能。 這些功能背後的想法是突出顯示有問題的圖像,以便可以修復它們 - 而不會完全破壞網站。
unsized-media
功能策略查找在 HTML 或 CSS 中未設置大小的圖像或視頻。 加載未調整大小的媒體元素時,可能會導致頁面上的內容重排。
為了防止將任何未調整大小的媒體添加到站點,請設置以下標頭。 然後媒體將以 300×150 像素的默認大小顯示。 您將看到您的網站加載了小型媒體,並意識到您有問題需要解決。
Feature-Policy: unsized-media 'none'
查看演示(需要具有實驗性 Web 平台功能的 Chrome Canary)。
oversized-images
功能策略檢查以查看圖像是否比它們的容器大。 如果是,則會顯示一個佔位符。 此策略對於檢查您是否沒有向移動用戶發送大量桌面圖像非常有用。
Feature-Policy: oversized-images 'none'
查看演示(需要具有實驗性 Web 平台功能的 Chrome Canary)。
unoptimized-images
功能策略檢查圖像的數據大小(以字節為單位)是否比其渲染區域(以像素為單位)大 0.5 倍。 如果啟用了此政策並且圖像違反了它,則會顯示佔位符而不是圖像。
Feature-Policy: unoptimized-images 'none'
查看演示(需要具有實驗性 Web 平台功能的 Chrome Canary)。
測試和報告功能策略
Chrome DevTools 將顯示一條消息,通知您某些功能已被功能策略阻止或啟用。 如果您在您的站點上啟用了功能策略,您可以檢查它是否有效。
對功能策略的支持也已添加到安全標頭站點,這意味著您可以在您的站點或網絡上的其他站點上檢查這些標頭以及諸如內容安全策略之類的標頭。
有一個 Chrome DevTools 擴展,可以讓您打開和關閉不同的功能策略(也是檢查頁面而無需配置任何標題的好方法)。
如果您想將您的功能策略與報告 API 集成,那麼這裡有關於如何執行此操作的更多信息。
進一步閱讀和資源
我找到了許多資源,其中許多是我在研究本文時使用的。 這些應該為您提供在您自己的應用程序中開始實施功能策略所需的一切。 如果您已經在使用內容安全策略,這似乎是控制您的網站與瀏覽器一起使用的方式的又一個合乎邏輯的步驟,以幫助確保使用您網站的人的安全和隱私。 您還可以使用功能策略來幫助您掌握隨著時間的推移添加到您的網站的性能破壞性元素的額外好處。
- 功能策略規範
- 介紹功能政策
- 來自 Chrome 開發者峰會的觀點
- MDN 上的功能策略
- 我可以使用功能策略嗎
- 功能政策演示
- 在 Nginx 中設置 Feature-Policy、Referrer-Policy 和 Content Security Policy 標頭