Permissions-Policy
Permissions-Policy 控制页面可以使用哪些浏览器能力(摄像头、麦克风、地理位置等),是 Feature-Policy 的继任者。
#type / concept
#status / evergreen
#tech / security
#resource / http
#platform / browser
[!info] related notes
- 所属 MOC: security-moc
- 总览: http-response-headers
- 并列安全头: CSP, HSTS, x-content-type-options, x-frame-options, referrer-policy
Permissions-Policy
一句话定义
Permissions-Policy 告诉浏览器:这个页面可以使用哪些浏览器能力(摄像头、麦克风、地理位置、支付等),不在白名单内的能力会被禁用。
它要解决什么问题
现代浏览器提供了很多强大的 API:摄像头、麦克风、地理位置、USB、陀螺仪、支付等。如果页面被 XSS 注入或者加载了恶意第三方脚本,这些能力可能被滥用。
Permissions-Policy 让你声明”这个页面只需要哪些能力”,其他的全部禁用。
指令语法
禁用某个能力
Permissions-Policy: camera=(), microphone=(), geolocation=()
空括号 () 表示禁止所有来源使用该能力。
只允许自己使用
Permissions-Policy: geolocation=(self)
self 表示只有当前 origin 的页面可以使用。
允许特定来源
Permissions-Policy: geolocation=(self "https://maps.example.com")
允许特定 iframe
Permissions-Policy: camera=(self "https://video-chat.example.com")
常见能力列表
| 能力 | 控制什么 | 典型禁用场景 |
|---|---|---|
camera | 摄像头 | 非视频类网站 |
microphone | 麦克风 | 非音频类网站 |
geolocation | 地理位置 | 非地图类网站 |
payment | 支付 API | 非电商网站 |
fullscreen | 全屏模式 | 不需要全屏的页面 |
usb | USB 设备访问 | 大多数网站 |
accelerometer | 加速度传感器 | 非游戏/AR 网站 |
gyroscope | 陀螺仪 | 非游戏/AR 网站 |
magnetometer | 磁力计 | 大多数网站 |
interest-cohort | FLoC(已废弃) | 隐私敏感场景 |
browsing-topics | Topics API | 隐私敏感场景 |
推荐配置
普通网站(不需要特殊能力)
Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=(), usb=()
地图网站(需要地理位置)
Permissions-Policy: camera=(), microphone=(), geolocation=(self), payment=(), usb=()
视频会议网站
Permissions-Policy: camera=(self), microphone=(self), geolocation=(), payment=()
Feature-Policy(已废弃)
Permissions-Policy 是 Feature-Policy 的继任者。主要区别:
| 方面 | Feature-Policy(旧) | Permissions-Policy(新) |
|---|---|---|
| 语法 | Feature-Policy: vibrate 'none' | Permissions-Policy: vibrate=() |
| 来源指定 | 'self' https://example.com | (self "https://example.com") |
| 状态 | 已废弃 | 推荐 |
如果维护旧代码,注意将 Feature-Policy 迁移到 Permissions-Policy。
边界与易混淆点
- Permissions-Policy 是页面级策略:通过响应头设置后,影响该页面及其嵌入的所有 iframe。
- 它不阻止加载资源:资源加载由 CSP 控制。Permissions-Policy 管的是浏览器 API 能力。
- 禁用能力后,相关 API 调用会直接失败:比如禁用
geolocation后,navigator.geolocation.getCurrentPosition()会抛出NotAllowedError。 - iframe 也可以有自己的 Permissions-Policy:通过
<iframe allow="...">属性设置,但不能超过父页面的权限范围。