Privacy & Security

Permissions-Policy 标头实际能锁定什么

一份实用指南,说明你可以限制哪些浏览器功能、哪些内容无法控制,以及如何在不破坏有用功能的前提下部署该标头。

The Wux Webtools Team The Wux Webtools Team 8 分钟阅读 人工智能辅助,人工审核
A browser interface with feature toggles limiting access for a page and embedded frames.
目录
  1. 简短版
  2. Permissions-Policy 控制什么
  3. 它能在你自己的页面上锁定什么
  4. 它能在 iframe 中锁定什么
  5. 它不能锁定什么
  6. 一个合理的默认策略
  7. 如何部署而不破坏功能
  8. 1. 盘点功能使用情况
  9. 2. 从低风险环境开始
  10. 3. 必要时使用页面级策略
  11. 4. 验证真实响应
  12. 5. 记录例外
  13. 常见语法错误
  14. 实际的隐私价值

简短版

Permissions-Policy 是一个 HTTP 响应标头,允许站点限制对某些浏览器功能的访问:摄像头、麦克风、地理位置、全屏、支付、传感器,以及一长串较小的 API。

它不是通用的隐私护盾。它不会阻止所有跟踪、拦截 cookies、防止网络请求,或让第三方 JavaScript 变得安全。它擅长的事情范围更窄,但仍然有价值:减少你自己的页面和嵌入式 frame 可用的浏览器能力。

这很重要,因为现代网站是由分析片段、媒体嵌入、聊天小组件、同意管理器、广告脚本、地图、支付流程和内部实验拼接而成的。大多数这些组件并不需要访问强大的设备 API。好的策略会把这一点明确下来。

如果你已经在生产环境中审查标头,请把这项工作与对实际响应的直接检查结合起来。我们的指南 debugging redirects and HTTP headers in production 介绍了这里真正重要的习惯:检查浏览器实际收到的内容,而不是你的配置文件声称应该发生的事情。

Permissions-Policy 控制什么

该标头控制对具名浏览器功能的访问。准确列表会随着时间变化,因为浏览器 API 也在变化,但常见指令包括:

  • camera
  • microphone
  • geolocation
  • fullscreen
  • payment
  • usb
  • bluetooth
  • accelerometer
  • gyroscope
  • magnetometer
  • screen-wake-lock
  • clipboard-read
  • clipboard-write
  • publickey-credentials-get
  • 早期讨论中的 interest-cohort,现在基本属于历史内容

一条指令可以不允许任何人使用某项功能,也可以允许当前 origin 使用,或允许选定的 origins 使用。例如:

Permissions-Policy: camera=(), microphone=(), geolocation=(self)

这表示摄像头和麦克风对该 document 及其嵌套浏览上下文禁用,而地理位置仅允许同源使用。

一个更宽松的示例:

Permissions-Policy: geolocation=(self "https://maps.example"), fullscreen=(self "https://video.example")

这允许你自己的 origin 和一个指定的地图提供商使用地理位置,并允许你自己的 origin 加上一个视频提供商请求全屏。

策略由浏览器评估。如果某项功能被禁止,使用该 API 的 JavaScript 应该失败或表现为不可用。具体失败方式取决于 API。有时 promise 会 reject。有时某项能力只是看起来无法使用。

它能在你自己的页面上锁定什么

在第一方页面上,Permissions-Policy 最有用的角色是护栏。它会降低意外代码或非预期代码的影响范围。

例如,一个营销页面很可能不需要麦克风、摄像头、Bluetooth、USB、运动传感器或支付 API。你可以全局拒绝这些功能:

Permissions-Policy: camera=(), microphone=(), bluetooth=(), usb=(), payment=(), accelerometer=(), gyroscope=(), magnetometer=()

这并不会让页面上的每个脚本都变得可信。但它意味着,如果标签管理器实验、被攻破的依赖项或粘贴进来的小组件尝试调用受限 API,浏览器不应授予其访问权限。

对于有许多贡献者的团队来说,这是一个有用的默认值。它把讨论从模糊的信任转向明确的能力。如果未来某个功能确实需要摄像头,就必须有人修改策略并解释原因。

这正是合适的阻力。

它能在 iframe 中锁定什么

围绕嵌入式内容时,该标头尤其有用。

浏览器已经将 iframe 视为独立的浏览上下文,但如果策略和 iframe 属性允许,嵌入的第三方内容仍然可以请求强大的功能。Permissions-Policy 让父页面可以设置上限。

例如,如果你的页面嵌入了视频播放器、支持小组件和地图,你可以避免让每个 frame 都访问所有功能。你可以只允许视频 frame 使用全屏,只允许地图 frame 使用地理位置。

这里需要理解两层:

  1. HTTP Permissions-Policy 标头为 document 设置策略。
  2. iframe allow 属性可以向某个 frame 委派特定功能,但只能在父策略允许的范围内进行。

一个简单的 iframe 可能如下所示:

<iframe src="https://video.example/embed/123" allow="fullscreen"></iframe>

如果你的标头完全拒绝全屏,iframe 属性无法覆盖该拒绝。如果你的标头允许该 origin 使用全屏,iframe 属性就可以进行委派。

这种层级关系是该标头值得使用的原因之一。它让平台或安全团队能够设置站点范围的边界,同时仍允许产品团队在需要的地方启用特定嵌入。

它不能锁定什么

这是团队有时会高估该标头的地方。

Permissions-Policy 不能替代内容安全策略。它不决定可以加载哪些脚本。它不会阻止脚本通过网络发送数据。它不会清理 HTML。它不会防止 XSS。它不会拦截表单垃圾信息。如果表单滥用是问题所在,应从 why your contact form is your biggest spam liability 中描述的机制入手,而不是从这个标头入手。

它也不能替代 cookie 治理。Cookies、本地存储、同意、第三方嵌入和浏览器跟踪保护是彼此独立的问题。如果你正在广泛审查隐私控制,cookie 领域值得单独过一遍;实际变更可参见 what changed for cookies in 2026 and what to do about it

最重要的是,Permissions-Policy 不会让第三方 JavaScript 变得私密。如果你把第三方脚本加载到第一方页面中,它通常会以你的页面权限运行,受其他浏览器约束和你的安全标头限制。拒绝摄像头访问是好事。但这并不能阻止该脚本读取 DOM 内容、观察用户操作,或发起被允许的网络请求。

为此,你需要不同的控制措施:谨慎选择供应商、CSP、沙盒化 iframe、适用时使用 Subresource Integrity、数据最小化,以及乏味但必要的审查。

一个合理的默认策略

没有一个适合所有站点的通用标头,但大多数内容站点和营销站点都可以从限制性策略开始。

一个合理的第一版:

Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=(), usb=(), bluetooth=(), accelerometer=(), gyroscope=(), magnetometer=(), screen-wake-lock=()

然后只加回站点实际使用的功能。

例如:

  • 使用 Payment Request API 的商店可能需要 payment=(self)
  • 位置查找器可能需要 geolocation=(self) 或一个可信的地图 origin。
  • 会议应用可能需要 camera=(self)microphone=(self)
  • 视频较多的站点可能需要 fullscreen=(self "https://trusted-video.example")

重要的是,不要从清单中复制一份巨大的策略就宣称完成。先从你的功能清单开始。哪些页面需要哪些浏览器能力?哪些嵌入需要委派?如果哪些功能被请求,会让人感到意外?

如何部署而不破坏功能

像部署任何其他生产标头一样推出它:有意识地进行。

1. 盘点功能使用情况

在代码库中搜索浏览器 API 调用,例如 getUserMediageolocationrequestFullscreenPaymentRequest、Web Bluetooth、WebUSB 和 wake lock API。

然后检查第三方嵌入。视频、地图、支付和身份提供商的文档通常会提到所需的 iframe allow 值。

2. 从低风险环境开始

在 staging 中添加限制性标头并测试核心路径。注意浏览器控制台消息。浏览器通常会报告某项功能何时被 permissions policy 阻止。

3. 必要时使用页面级策略

如果你的产品有非常不同的页面类型,不要强行使用一个全局策略。博客、结账页、地图页和视频房间很可能需要不同的能力。

大多数 Web 服务器、框架和 edge 平台都可以按路径有条件地设置标头。这通常比为了一个功能削弱整个站点更干净。

4. 验证真实响应

CDN、反向代理、应用服务器和中间件可能会添加、覆盖、重复或剥离标头。请在浏览器 DevTools 中或使用命令行工具检查最终响应。

还要测试嵌入式上下文。顶层页面看起来正确,并不能保证 iframe 收到了你预期的委派。

5. 记录例外

每个被允许的功能都应该有负责人和理由。这听起来官僚,直到六个月后,没人记得为什么曾经把 geolocation 开放给一个页面上已经看不到的供应商域名。

常见语法错误

现代标头语法很紧凑,但也很容易稍微写错。

使用空括号拒绝某项功能:

Permissions-Policy: microphone=()

使用 self 表示当前 origin:

Permissions-Policy: geolocation=(self)

使用带引号的 origins 表示特定外部 origins:

Permissions-Policy: fullscreen=(self "https://video.example")

避免依赖旧的 Feature-Policy 示例,除非你有意支持旧版行为。旧标头使用不同语法,不应作为今天设计的基础。

还要记住,浏览器支持会因指令而异。浏览器可能支持该标头,但不支持某个特定功能指令。这是正常的。应把该标头视为纵深防御措施,而不是唯一的隐私或安全控制。

<!-- tool-cta:start -->

💡 试试这个: 使用 Get Headers 验证你的 Permissions-Policy 是否按预期传送,它会显示服务器正在发送的原始响应标头。

<!-- tool-cta:end -->

实际的隐私价值

Permissions-Policy 的隐私价值不在于让站点匿名或没有跟踪器。它做不到。

它的价值在于缩小对敏感浏览器能力的访问范围。位置、摄像头、麦克风、设备传感器、本地硬件 API 和支付流程都很强大。大多数页面并不需要它们。许多嵌入式组件永远不应该能够请求它们。

这是真实的改进。它减少意外提示,限制不必要的能力暴露,并为你的团队在新功能发布时提供一个可审查的具体产物。

这个标头的最佳状态是平淡无奇:默认限制,仅在面向用户的功能需要时放宽,并作为正常发布流程的一部分进行测试。

常见问题

Permissions-Policy 和 Feature-Policy 是一回事吗?
不是。Permissions-Policy 是较旧的 Feature-Policy 标头的现代替代品。一些旧文章和代码片段仍使用 Feature-Policy 语法,但新的实现应使用 Permissions-Policy。
Permissions-Policy 能阻止第三方跟踪吗?
单靠它不能。它可以阻止对某些浏览器功能的访问,但不会阻止脚本加载、在被允许时设置 cookies、读取页面内容或发送网络请求。请将它与 CSP、同意控制、数据最小化和谨慎的供应商管理配合使用。
每个站点都应该拒绝摄像头和麦克风吗?
大多数站点应该这样做,是的。如果你的站点不提供视频录制、会议、身份验证或其他明确需要媒体采集的功能,拒绝摄像头和麦克风是一个合理的默认值。
iframe allow 属性能覆盖标头吗?
不能。父 document 策略设置上限。只有当父策略允许该 frame origin 使用某项功能时,iframe allow 属性才能委派该功能。
不受支持的指令会破坏旧浏览器吗?
通常,不受支持的指令会被忽略。你仍然应该在支持的浏览器范围内测试重要用户路径,因为具体 API 行为和控制台报告可能会有所不同。

来源与进一步阅读

  1. MDN Web Docs: Permissions-Policy header
  2. W3C: Permissions Policy specification
  3. web.dev: Permissions Policy
  4. Chrome Developers: Controlling browser features with Permissions Policy
关于作者
The Wux Webtools Team

最后更新:

继续阅读