网页用不到的摄像头和定位能力,怎么在响应头里默认关掉
网页用不到的摄像头、麦克风和定位能力,可以在 Permissions-Policy 这个响应头里默认关掉。它的作用机制是给每条指令设定一个允许名单,文档本身以及文档里嵌套的每一个框架都按这份名单来判断能不能使用对应功能。把站点的默认名单收紧到「谁都不给」,是缩小浏览器能力暴露面最直接的一层。
默认名单只有三种取值
按文档说明,每条指令都有一份默认允许名单,取值始终是三种之一:星号表示任何来源都允许,self 表示仅同源,none 表示默认谁都不给。也就是说,写这份头的本质不是「关掉某个功能」,而是把每条指令的默认名单从宽改成窄。
下面这张表把常见指令按「页面到底用不用得上」分开列,便于逐项判断该给哪一档:
| 能力类别 | 典型指令 | 内容站常见的名单 |
|---|---|---|
| 硬件采集 | 摄像头、麦克风 | 无相关功能时给空名单 |
| 位置信息 | 定位 | 门店定位一类页面才需要给同源 |
| 画面捕获 | 屏幕共享 | 一般给空名单 |
| 全屏与自动播放 | 全屏、自动播放 | 视频类页面按需给同源 |
| 跨站请求 | 通配子域相关指令 | 未使用时给空名单 |
嵌套框架为什么会被父页面卡住
文档里有一条经常被忽略的前提:框架要启用某项功能,它的允许来源必须同时出现在父页面的允许名单里。这意味着父页面名单是上限,子框架拿不到超出上限的授权。
内容站上的第三方组件正是走这条路:嵌入的验证码组件、地图组件、播放器都嵌在框架里。如果为了收紧名单把父页面设成空,这些组件就会直接失效。实践中的顺序应当是先确定整站可接受的最宽范围写进响应头,再在需要更窄的框架上用 allow 属性指定它自己需要的那个子集。
allow 属性只能收窄,不能放宽
这是第二条边界:框架上的 allow 属性用来在父页面允许的范围内进一步收窄,而不是给子页面追加权限。父页面没给的授权,写再多属性也不会出现。
排查时这一点最容易误判。组件报「浏览器拒绝了该能力」,先看的是父页面响应头里的名单,而不是组件文档里的参数写法。
这一头和站内已有防护不重叠
AnQiCMS 这类系统在输入侧已有防护,敏感词过滤与针对 SQL 注入、XSS 的过滤逻辑处理的是内容层面的问题;Permissions-Policy 处理的是浏览器功能调用权限,属于「页面能不能访问设备能力」这一层。两者都不越界:收紧能力名单不能替内容做净化,内容过滤也不会让越权的框架调用失败。
表单里接了验证码组件的站点要注意,收紧名单之后的验证顺序应当是:先在一个干净的浏览器实例里确认组件仍能正常加载与提交,再确认后端依旧对提交做校验。人机验证组件在页面上是否可用属于浏览器侧,服务端仍然要独立判断这一次提交是否合法,不能因为页面已经有组件就默认通过。
常见问题
问:一条指令都不写会怎样? 答:各指令按其默认允许名单运行,而不同指令的默认档并不一致。逐项写明是把行为显式化,避免依赖各功能的默认设置。
问:只给同源是不是更安全? 答:同源只是三档之一,适用于只有本站脚本会调用该能力的情况。若确实没有任何场景用到,空名单比同源更窄。
问:改了头之后为什么有的页面还是弹权限? 答:该页面在名单里被允许了,或响应头没有覆盖到这条路径。逐路径核对下发位置比只在主站加一条更稳。