题干与适用场景
你负责一个仪表盘,嵌入 meet.example 会议、video.example 播放器和多个广告 frame。会议需要 microphone 与 camera,播放器需要 fullscreen,广告不需要这些能力。页面使用 HTTPS;源站已知;策略允许时浏览器仍应向用户请求媒体授权。
题目范围是浏览器策略组合与故障诊断。CSP、身份认证和服务端授权仍是独立控制。假设仪表盘服务器设置响应头,且每个跨域 frame 都显式设置 allow。
面试官考察点
面试官会看你能否拆开三个闸门:响应策略、frame 委托、用户运行时授权。只有响应头列出源并不会自动给跨域 frame 权限;allow 也不能扩大被响应头拒绝的能力。
强回答从敏感能力的 () 默认拒绝开始,写出精确源、处理导航和嵌套 frame,并说明 API 不可用时的界面行为。弱回答会直接写 *、等待权限弹窗,再把“安全”当成结论。
回答前需要澄清的问题
- 会议 frame 可能导航到哪些确切源?导航到新源后,原有能力可能需要重新委托,否则应被拒绝。
- 会议 frame 是否还会嵌套其他 frame?如果会,要定义委托能否继续,并逐层验证实际源。
- 支持哪些浏览器和内嵌 WebView?语法正确不代表所有运行时的失败表现相同。
- 摄像头和麦克风是否必须?若可选,策略拒绝或用户拒绝时可以提供文字通话路径。
30 秒回答框架
“我会把摄像头和麦克风默认设为 (),只在响应策略中授予会议源;全屏只授予视频源。每个跨域 iframe 再通过 allow 写出所需能力,因为响应头和 frame 策略缺一不可。frame 分开识别策略拒绝与用户拒绝,展示降级路径,不把权限弹窗当成授权依据。上线前测试同源、跨域、导航、嵌套 frame、缺少响应头和浏览器降级。”
分步骤深入解答
第一步:建立默认拒绝清单
列出页面使用的每项策略控制能力及其所属源,不要从“会议”这个产品名推断权限。摄像头、麦克风是两项独立能力;全屏是另一项;广告属于明确的零权限类别。
可以使用显式响应头:
Permissions-Policy: camera=(self "https://meet.example"), microphone=(self "https://meet.example"), fullscreen=(self "https://video.example")精确源列表可以阻止无关 frame 获得授权。如果仪表盘自身也不应访问某能力,就移除 self,只授予必要的 frame 源,同时确认父策略仍允许委托。
第二步:在每个 iframe 边界委托
会议 frame 只得到两项能力,视频 frame 只得到全屏:
<iframe src="https://meet.example/room" allow="camera; microphone"></iframe>
<iframe src="https://video.example/player" allow="fullscreen"></iframe>
<iframe src="https://ad.example/slot" allow=""></iframe>跨域 frame 即使响应头列出了源,省略 allow 仍会被拦截。反过来,给广告加 allow="camera" 也不能覆盖 camera=() 或响应头中没有列出的源。
第三步:分开处理策略和用户同意
Permissions-Policy 决定文档能否使用能力;Permissions API 与媒体弹窗代表用户授权。策略阻断可能发生在弹窗出现之前。frame 应把“策略拒绝”“用户拒绝”“不支持”和“设备占用”分别记录并给出恢复动作。
客户端检查不是安全边界。嵌入页控制委托,应用仍需在服务端认证通话并校验房间成员资格。
第四步:明确处理导航与嵌套 frame
如果会议 frame 能导航到支持源,只有在该源可信且确实需要相同能力时,才把目的源加入 allow 策略。初始 src 源和之后的导航源不是同一个授权对象。嵌套 frame 要逐层检查有效策略,归属不明时默认拒绝。
第五步:用可观察测试上线
在平台允许的情况下先以诊断或小流量路由观察,再比较策略违规、弹窗结果、通话完成率和降级使用率。测试同源 frame、已允许跨域 frame、未列出的跨域 frame、缺少 allow、变化的子域名和 frame 导航。应断言广告永远不会触发弹窗,会议被拒绝时会显示文字聊天。
高质量示范回答
“我会从威胁模型写策略。摄像头和麦克风先设为空权限,只在响应头列出 meet.example;全屏只列出 video.example。两个跨域 frame 带匹配的 allow,广告 frame 不带能力。浏览器仍负责用户同意,所以会议代码要区分策略拦截和用户拒绝,并提供文字降级。这个头不负责授权房间,服务端仍要检查用户身份和成员关系。
上线前我会覆盖矩阵:允许与未列出的源、同站但跨域的子域名、省略 allow、frame 导航、嵌套 frame、不支持浏览器和缺失响应头。遥测只记录能力、frame 源、策略结果、用户结果和降级,不记录媒体内容。广告出现意外弹窗,或导航到不可信源后仍能使用能力,就暂停发布。”
常见错误
- 摄像头和麦克风使用
*→ 任意合资格 frame 都可能请求敏感能力 → 从()开始,只添加确切源。 - 只设置 HTTP 头 → 跨域 iframe 还需要容器委托 → 设置匹配的
allow。 - 只设置
allow→ frame 不能扩大父策略 → 同时检查响应头和每个 frame 边界。 - 把没有弹窗当成浏览器故障 → 策略拒绝可能早于用户同意 → 分开记录策略、用户、支持性和设备状态。
- 认为子域名就是同源 → 同站不等于同源 → 逐个列出源并测试导航。
追问及应对
追问一:响应头列出了会议源,为什么功能仍被拦截?
检查 iframe 的 allow、协议与端口是否完全匹配,以及 frame 是否已导航。跨域 frame 的响应策略与容器策略取交集,任一授权缺失都会阻断能力。
追问二:能否省略响应头,只依赖 allow?
不能。显式响应策略给页面所有者提供顶层边界,避免新增第三方 frame 时意外放权。省略策略可能让某些能力采用宽松默认值,第三方嵌入就可能形成回归。
追问三:会议 frame 导航到支持域名时怎么办?
把目的源当成新的授权对象重新评估。只有完成信任、认证和数据处理审查后才授予摄像头或麦克风,否则导航后应失去能力并展示降级说明。
追问四:Permissions Policy 能替代服务端授权吗?
不能。它控制文档中浏览器能力的可用性,不能证明用户身份、房间成员关系或加入通话的业务权限。这些检查仍由服务端完成,策略只提供最小权限的浏览器边界。