Permissions-Policy 标头
>HTTP Permissions-Policy 响应标头提供了一种机制,用于允许或拒绝在文档中或文档内的任何 <iframe> 元素中使用浏览器特性。
可以使用报告 API 报告策略违规。报告可以发送到按指令指定的 report-to 参数所指示的服务器端点,否则发送到名为 "default" 的服务器端点(服务器端点名称与 URL 之间的映射使用 Reporting-Endpoints HTTP 响应标头设置)。还可以在强制执行策略的页面中使用 ReportingObserver 观察报告。报告的格式和更多细节参见 PermissionsPolicyViolationReport。
更多信息请参阅主文章权限策略。
| 标头类型 | 响应标头 |
|---|
语法
# 单个指令
Permissions-Policy: <directive>=<allowlist>
# 带有报告端点的单个指令
Permissions-Policy: <directive>=<allowlist>;report-to=<endpoint>
# 多个指令,包含和不包含服务器报告端点
Permissions-Policy: <directive>=<allowlist>, <directive>=<allowlist>;report-to=<endpoint>, ...
该标头可用于设置一个或多个指令的允许列表,并可选择设置按指令指定的 report-to 参数,指示要将策略违规报告发送到的服务器端点。每个指令的条目以逗号分隔。
<directive>-
要应用
allowlist的权限策略指令。允许的指令名称列表请参见下文的指令。 <allowlist>-
允许列表是一个来源列表,由括号中以下一个或多个值组成,并以空格分隔:
*(通配符)-
该特性将在本文档和所有嵌套的浏览上下文(
<iframe>)中被允许,无论其来源如何。 ()(空允许列表)-
该特性在顶层和嵌套浏览上下文中被禁用。这等效于
<iframe>allow属性为'none'。 self-
该特性将在本文档和所有同源的嵌套浏览上下文(
<iframe>)中被允许。该特性不允许在嵌套浏览上下文中的跨源文档内使用。self可以看作是https://your-site.example.com的简写。其等效于<iframe>allow属性为self。 src-
只要加载到此
<iframe>中的文档与其 src 属性中的 URL 同源,该特性就会在此<iframe>中被允许。此值仅在<iframe>allow属性中使用,并且是<iframe>中默认的allowlist值。 "<origin>"-
该特性允许用于指定特定来源(例如
"https://a.example.com")。来源应以空格分隔。注意,<iframe>allow 属性中的来源无需加引号。
值
*和()只能单独使用,而self和src可以与一个或多个来源组合使用。备注:指令具有默认的允许列表。对于
Permissions-PolicyHTTP 标头来说,默认允许列表始终是*、self或none之一,并用于控制未在策略中明确列出该指令时的默认行为。这些默认值在各个指令参考页面中指定。对于<iframe>allow属性,默认行为始终是src。 report-to=<endpoint>可选-
report-to参数可用于指定报告端点的名称,当关联指令发生策略违规时,报告将发送到该端点。端点名称及其关联 URL 必须在单独的Reporting-EndpointsHTTP 响应标头中指定。如果省略,报告将发送到
default报告端点(如果已定义)。详见报告 API。
在支持的情况下,你可以在权限策略来源中使用通配符。这意味着你不必在允许列表中明确指定多个不同的子域名,而是可以通过一个带通配符的来源将它们全部包含在内。
所以,与其写
("https://example.com" "https://a.example.com" "https://b.example.com" "https://c.example.com")
你可以写成
("https://example.com" "https://*.example.com")
备注:"https://*.example.com" 不匹配 "https://example.com"。
指令
accelerometer-
控制当前文档是否允许通过
Accelerometer接口收集设备加速度的相关信息。 ambient-light-sensor-
控制当前文档是否允许通过
AmbientLightSensor接口收集设备周围环境的光照强度信息。 aria-notify-
控制当前文档是否允许使用
ariaNotify()方法触发屏幕阅读器播报。 attribution-reporting-
控制当前文档是否允许使用 归因报告 API。
autoplay-
控制当前文档是否允许自动播放通过
HTMLMediaElement接口请求的媒体。当此策略被禁用且没有用户手势时,HTMLMediaElement.play()返回的Promise将因NotAllowedErrorDOMException而被拒绝。<audio>和<video>元素上的 autoplay 属性将被忽略。 bluetooth-
控制是否允许使用 Web 蓝牙 API。当此策略被禁用时,
Navigator.bluetooth返回的Bluetooth对象的方法将返回false或使返回的Promise因SecurityErrorDOMException而拒绝。 browsing-topics-
控制对主题 API 的访问。当策略明确禁止使用 Topics API 时,任何调用
Document.browsingTopics()方法或发送带有Sec-Browsing-Topics标头的请求都将失败并抛出NotAllowedErrorDOMException。 camera-
控制当前文档是否允许使用视频输入设备。如果未授予此权限,
getUserMedia()返回的Promise将因NotAllowedErrorDOMException而拒绝。 captured-surface-control-
控制文档是否被允许使用 Captured Surface Control API。如果未授予权限,该 API 主要方法返回的 promise 将因
NotAllowedErrorDOMException而被拒绝。 ch-ua-high-entropy-values-
控制文档是否被允许使用
NavigatorUAData.getHighEntropyValues()方法检索高熵用户代理数据。如果未授予此权限,该方法将仅返回brands、mobile和platform的低熵数据。 compute-pressure-
控制对 Compute Pressure API 的访问权限。
cross-origin-isolated-
控制当前文档是否可以被视为跨源隔离。
deferred-fetch-
控制顶级源的
fetchLater()配额分配。 deferred-fetch-minimal-
控制共享跨源子框架
fetchLater()配额的分配。 display-capture-
控制当前文档是否被允许使用
getDisplayMedia()方法捕获屏幕内容。当此策略被禁用时,如果未获得捕获显示内容的权限,getDisplayMedia()返回的 promise 将因NotAllowedErrorDOMException而被拒绝。 encrypted-media-
控制当前文档是否允许使用加密媒体扩展 API (EME)。当此策略被禁用时,
Navigator.requestMediaKeySystemAccess()返回的Promise将因SecurityErrorDOMException而拒绝。 fullscreen-
控制当前文档是否允许使用
Element.requestFullscreen()。当此策略被禁用时,返回的Promise将因TypeError而拒绝。 gamepad-
控制当前文档是否允许使用游戏手柄 API。当此策略被禁用时,调用
Navigator.getGamepads()将抛出SecurityErrorDOMException,并且gamepadconnected和gamepaddisconnected事件将不会触发。 geolocation-
控制当前文档是否允许使用
Geolocation接口。当此策略被禁用时,调用getCurrentPosition()和watchPosition()将导致这些函数的回调函数返回PERMISSION_DENIED的GeolocationPositionError错误代码。 gyroscope-
控制当前文档是否允许通过
Gyroscope接口收集有关设备方向的信息。 hid-
控制当前文档是否允许使用 WebHID API 连接非标准或特殊的人机界面设备,如替代键盘或游戏手柄。
identity-credentials-get-
控制当前文档是否允许使用联合凭证管理 API(FedCM)。
idle-detection-
控制当前文档是否允许使用空闲检测 API 检测用户何时正在与设备交互,例如在聊天应用中报告“在线”/“离开”状态。
language-detector-
控制对翻译器和语言检测 API 语言检测功能的访问权限。
local-fonts-
控制当前文档是否允许通过
Window.queryLocalFonts()方法收集用户本地安装的字体数据(参见本地字体访问 API)。 magnetometer-
控制当前文档是否允许通过
Magnetometer接口收集有关设备方向的信息。 microphone-
控制当前文档是否允许使用音频输入设备。当此策略被禁用时,
MediaDevices.getUserMedia()返回的Promise将因NotAllowedErrorDOMException而被拒绝。 midi-
控制当前文档是否允许使用 Web MIDI API。当此策略被禁用时,
Navigator.requestMIDIAccess()返回的Promise将因SecurityErrorDOMException被拒绝。 on-device-speech-recognition-
控制对 Web Speech API 的设备端语音识别功能的访问权限。
otp-credentials-
控制当前文档是否允许使用 WebOTP API 从应用服务器发送的特殊格式短信中请求一次性密码(OTP),即通过
navigator.credentials.get({otp: ..., ...})实现。 payment-
控制当前文档是否允许使用支付请求接口。当此策略被启用时,
PaymentRequest()构造函数将抛出SecurityErrorDOMException。 picture-in-picture-
控制当前文档是否允许通过相应的 API 以画中画模式播放视频。
private-state-token-issuance-
控制私有状态令牌
token-request操作的使用。 private-state-token-redemption-
控制私有状态令牌
token-redemption和send-redemption-record操作的使用。 publickey-credentials-create-
控制当前文档是否允许使用 Web 认证 API 创建新的非对称密钥凭证,即通过
navigator.credentials.create({publicKey: ..., ...})实现。 publickey-credentials-get-
控制当前文档是否允许使用 Web 认证 API 检索已存储的公钥凭证,即通过
navigator.credentials.get({publicKey: ..., ...})。 screen-wake-lock-
控制当前文档是否允许使用屏幕唤醒锁 API 指示设备不应关闭屏幕或调暗屏幕亮度。
serial-
控制当前文档是否允许使用 Web Serial API 与串行设备通信,无论是通过串行端口直接连接,还是通过模拟串行端口的 USB 或蓝牙设备连接。
speaker-selection-
控制当前文档是否允许使用音频输出设备 API 列出和选择扬声器。
storage-access-
控制在第三方上下文中加载的文档(即嵌入在
<iframe>中)是否允许使用存储访问 API 请求访问未分区的 cookie。 translator-
控制对翻译器和语言检测 API 翻译功能的访问权限。
summarizer-
控制对 Summarizer API 的访问权限。
usb-
控制当前文档是否允许使用 WebUSB API。
-
控制当前文档是否允许使用 Web 共享 API 的
Navigator.share()方法,将文本、链接、图像和其他内容分享到用户选择的任意目标,例如移动应用。 window-management-
控制当前文档是否允许使用 Window Management API 管理多显示器上的窗口。
xr-spatial-tracking-
控制当前文档是否允许使用 WebXR 设备 API 与 WebXR 会话进行交互。
示例
>基础用法
Permissions-Policy 标头
要允许所有来源访问地理位置,你可以这样做:
Permissions-Policy: geolocation=*
或者要允许一部分来源访问,你可以这样做:
Permissions-Policy: geolocation=(self "https://a.example.com" "https://b.example.com")
可以通过发送带有逗号分隔策略列表的标头,或为每个策略发送单独的标头来同时控制多个特性。
例如,以下两种写法是等效的:
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=*
iframes
要使 <iframe> 启用某个特性,其允许的来源也必须在父页面的允许列表中。由于这种继承行为,最好在 HTTP 标头中为特性指定最广泛的可接受支持范围,然后在每个 <iframe> 中指定所需的子集。
要允许所有来源访问地理位置,你可以这样做:
<iframe src="https://example.com" allow="geolocation *"></iframe>
要应用于当前来源和其他来源,你可以这样做:
<iframe
src="https://example.com"
allow="geolocation 'self' https://a.example.com https://b.example.com"></iframe>
这一点很重要:默认情况下,如果一个 <iframe> 导航到另一个来源,该策略不会应用于 <iframe> 导航到的来源。通过在 allow 属性中列出 <iframe> 导航到的来源,原本应用于原始 <iframe> 的权限策略将同样应用于 <iframe> 导航到的来源。
可以通过在 allow 属性中包含分号分隔的策略指令列表来同时控制多个特性。
<iframe
src="https://example.com"
allow="geolocation 'self' https://a.example.com https://b.example.com; fullscreen 'none'"></iframe>
值得一提的是 src 值。我们在上面提到,使用此允许列表值意味着,只要加载到其中的文档与其 src 属性中的 URL 同源,关联的特性将在此 <iframe> 中被允许。此值是 allow 中列出的特性的默认允许列表值,因此以下两种写法是等效的:
<iframe src="https://example.com" allow="geolocation 'src'"></iframe>
<iframe src="https://example.com" allow="geolocation"></iframe>
禁用强大特性的访问
SecureCorp 公司希望在其应用中禁用麦克风(例如 MediaDevices.getUserMedia())和 Geolocation API。可以通过以下响应标头实现:
Permissions-Policy: microphone=(), geolocation=()
通过为来源列表指定 (),无论其来源如何,所有浏览上下文(包括所有 <iframe>)中指定的特性都将被禁用。
组合 HTTP 标头和 <iframe> 策略
例如,假设我们想在自己的来源和来自我们信任的广告网络的嵌入内容中启用地理位置使用。我们可以这样设置页面范围的权限策略:
Permissions-Policy: geolocation=(self https://trusted-ad-network.com)
在我们的广告 <iframe> 中,我们可以这样设置对 https://trusted-ad-network.com 来源的访问权限:
<iframe src="https://trusted-ad-network.com" allow="geolocation"></iframe>
如果最终加载到 <iframe> 中的是其他来源,则该来源将无法访问地理位置信息:
<iframe src="https://rogue-origin-example.com" allow="geolocation"></iframe>
报告违规
此示例展示如何将 Permissions-Policy 违规报告配置到服务器端点。
以下响应标头阻止了地理位置功能,并将该功能的报告端点名称定义为 "geo_endpoint"。Reporting-Endpoints HTTP 响应标头用于定义该端点名称的 URL。
Reporting-Endpoints: geo_endpoint="https://example.com/reports"
Permissions-Policy: geolocation=();report-to=geo_endpoint
备注:如果要将所有违规报告发送到同一端点,可以改为定义 "default" 报告端点:
Reporting-Endpoints: default="https://example.com/reports"
Permissions-Policy: geolocation=()
当页面尝试使用被阻止的功能时,就会发生违规,例如:
navigator.geolocation.getCurrentPosition(
() => {},
() => {},
);
发送到端点的报告负载可能如下所示:
[
{
"age": 48512,
"body": {
"columnNumber": 29,
"disposition": "enforce",
"lineNumber": 44,
"message": "Permissions policy violation: geolocation access has been blocked because of a permissions policy applied to the current document.",
"featureId": "geolocation",
"sourceFile": "https://example.com/"
},
"type": "permissions-policy-violation",
"url": "https://example.com/",
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36"
}
]
备注:Chrome 在服务器端序列化违规报告时,使用 policyId 而非 featureId 作为报告中 body 里的功能名称。由 ReportingObserver 返回的 PermissionsPolicyViolationReport 遵循规范。
规范
| 规范 |
|---|
| Permissions Policy> # permissions-policy-http-header-field> |