使用功能策略保护您的网站
已发表: 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 标头