前端面试:如何安全地为浏览器代理暴露 WebMCP 工具?
题目
电商结账页准备试用 WebMCP,让浏览器代理替用户筛选商品并填写表单。你如何定义工具、限制权限、保留用户控制,并验证代理不会误调用高风险动作?
场景与适用边界
WebMCP 是提议中的 Web 标准,Chrome 文档描述了声明式 HTML 表单工具和命令式 JavaScript 工具;Chrome 149 开始提供 origin trial。题目讨论浏览器标签页内、有人在环的渐进增强,不把 WebMCP 当作已经稳定、可在无浏览器上下文中运行的后端协议,也不把它当成替代服务端授权的安全边界。
回答前可以确认:哪些动作只是筛选和填充,哪些动作会下单或扣款?工具只对顶层页面可见,还是要暴露给跨来源 iframe?用户是否必须在最终提交前再次确认?如何处理代理不支持 WebMCP 或 origin trial 结束?
面试官考察点
考察你能否把代理可调用性设计成前端契约:工具描述和输入 schema 足够明确,调用仍经过现有登录、CSRF、业务授权和用户确认,跨来源暴露遵循最小权限,并用评估集验证调用选择、参数和结果。
30 秒回答框架
先把用户旅程拆成只读、可逆和不可逆动作;只读筛选可用声明式或命令式工具,提交订单保持服务端授权和明确确认。工具 schema 只暴露必要字段,默认限制在当前页面和来源,跨来源 iframe 需要显式 Permissions Policy。发布前用真实任务评估工具选择、参数校验、错误处理和拒绝路径,并保留 DOM 操作降级。
分步骤深入解答
- 划分风险:
search、filter、fill属于低风险或可逆动作;place-order、pay、修改地址属于高影响动作,不能因为代理拿到工具就自动执行。 - 设计契约:每个工具有稳定名称、面向代理的描述、JSON 输入 schema 和结构化结果;枚举、范围、币种、库存版本等约束在前端和服务端都校验。
- 复用业务逻辑:工具回调调用现有表单状态和领域函数,不复制一套绕过用户界面的请求;执行前检查登录、购物车版本、CSRF、价格和库存。
- 权限边界:默认只在顶层窗口和同源上下文暴露;跨来源 iframe 只有在
Permissions-Policy和 iframeallow明确允许时才共享工具,工具不得返回不必要的个人资料。 - 用户控制:筛选和填充可以先执行并展示变更;下单、付款、删除等动作要求页面内确认和可见摘要,工具结果说明是否完成、等待确认或被拒绝。
- 渐进发布:在本地 flag 或 origin trial 中先对内部账号启用,提供能力检测、无 WebMCP 时的正常 UI 和 DOM 自动化降级;记录工具版本、调用结果和拒绝原因。
- 评估与监控:建立任务集,测工具选择准确率、参数合法率、完成率、误调用率、拒绝正确率和用户确认覆盖率;对高风险工具设置零误调用门槛,发现异常立即撤销注册。
高质量示范回答
我会先把结账旅程拆成筛选、填充和提交三个阶段。筛选与填充是可逆动作,可以使用 WebMCP 工具改善代理定位;下单和付款仍由现有服务端授权、价格库存校验和页面确认决定。WebMCP 是实验性提议,Chrome 149 的 origin trial 只适合受控验证,不能代替后端权限。
工具只声明完成当前用户旅程所需的最小字段,并在回调中复用现有表单和领域逻辑。输入 schema 限制商品 ID、数量和地址格式,服务端再次校验登录、CSRF、库存、价格和订单幂等键。默认只暴露给顶层页面和同源代理;若必须支持跨来源 iframe,就同时配置权限策略和 iframe allow,不把整套账户数据返回给工具。
const controller = new AbortController();
document.modelContext?.registerTool({
name: "cart_set_quantity",
description: "Set the quantity of one visible cart item; never submits an order.",
inputSchema: {
type: "object",
properties: {
itemId: { type: "string", minLength: 1 },
quantity: { type: "integer", minimum: 1, maximum: 10 }
},
required: ["itemId", "quantity"]
},
async execute({ itemId, quantity }) {
const result = await setVisibleCartQuantity(itemId, quantity);
return { content: [{ type: "text", text: result.summary }] };
}
}, { signal: controller.signal });下单工具即使存在,也只返回“需要用户确认”,不能自行扣款。每次调用记录工具版本、参数校验结果和页面状态;评估集覆盖错误商品、过量数量、过期价格、拒绝确认和 WebMCP 不可用。这样 WebMCP 是可撤销的渐进增强,业务授权和用户意图仍由现有链路决定。
常见错误
- 把 WebMCP 早期试用功能描述成稳定的后端 API。
- 暴露一个能直接付款、删除账户或修改任意地址的万能工具。
- 只在浏览器端校验 schema,服务端不再检查登录、库存、价格和幂等性。
- 让跨来源 iframe 默认共享工具,或把完整用户资料作为工具结果返回。
- 没有正常 UI、能力检测、撤销注册和代理评估集。
高质量回答应同时覆盖工具契约、服务端授权、来源隔离、用户确认、降级和量化评估。只说“给按钮加描述”无法证明交互安全。
追问及应对
为什么不把下单也注册成 WebMCP 工具?
可以注册一个只负责准备订单摘要的工具,但最终提交应由页面确认和服务端授权完成。工具调用本身不能证明用户同意付款,也不能绕过价格、库存和风控校验。
如何限制跨来源 iframe 的工具暴露?
默认不暴露给跨来源上下文;确有需要时同时使用明确的 Permissions-Policy 和 iframe allow,并在工具层限制可读写的数据范围。来源、页面生命周期和撤销路径都应进入日志。
代理传入了 schema 合法但业务无效的参数怎么办?
前端先拒绝不可见商品、过期状态和超出当前用户范围的输入,服务端再次执行业务校验,返回结构化拒绝原因;不要把字符串拼接成任意动作,也不要静默修改参数。
如何证明代理真的理解工具?
用固定任务集和真实页面评估工具选择、参数合法率、完成率、误调用率和拒绝正确率。对付款、删除等高风险动作设置零误调用门槛,并在 API 变化后重新评估。