MCP Apps 安全教程封面,展示 AI 客户端中的 HTML 面板、XSS 风险与 iframe Sandbox 防护

MCP Apps 安全教程:AI 客户端里的 HTML、Stored XSS 与 Sandbox 怎么防

MCP Apps 不应只依赖 iframe 沙箱。本文提供从安全 DOM 渲染、HTML 清洗、CSP、消息校验到工具授权与审计的完整防护方案。

摘要: MCP Apps 把仪表盘、表单和审批界面直接带进 AI 客户端,也把传统 Web 的 HTML 注入、Stored XSS、危险 DOM API 与跨窗口消息风险带进了 Agent 工作流。最重要的结论是:iframe Sandbox 负责隔离,CSP 负责缩小资源与联网范围,输出编码和 HTML 清洗负责阻止脚本进入 DOM,而工具授权、人工确认与审计负责阻止被攻陷的界面借宿主执行高风险动作。本文适合 MCP Server 开发者、AI 客户端团队和企业安全人员,可直接用于设计、测试和验收 MCP App;建议在生产接入前完成本文的七层防护与测试矩阵。

核心结论

MCP Apps 的 HTML 必须同时按“不可信网页”和“Agent 工具入口”治理。只给 iframe 加 sandbox 并不能解决 Stored XSS;如果应用把数据库、工具结果或模型输出直接写入 innerHTML,恶意内容仍可能在 App 自己的隔离域中执行,并通过被允许的 JSON-RPC、网络出口或工具调用扩大影响。

  • 值得使用,但必须安全默认。 MCP Apps 适合数据可视化、复杂表单和多步审批;宿主应默认拒绝网络、嵌套 iframe 和敏感浏览器权限。
  • Stored XSS 的根因不在 iframe。 根因是“不可信持久化数据进入危险 HTML/DOM 上下文”;首选 textContent,确需富文本时使用维护中的 HTML 清洗库并限制标签、属性和 URL 协议。
  • Sandbox 是损害控制,不是输入过滤器。 它隔离父页面 DOM、Cookie 与存储,但 App 内执行的恶意脚本仍可能看到该 App 收到的数据、触发界面欺骗或请求允许的能力。
  • CSP 必须最小化。 connectDomains、resourceDomains、frameDomains 和 baseUriDomains 只列业务必需来源,生产环境不得保留通配符和临时开发域名。
  • 所有 App 发起的高风险工具调用都要在宿主侧重新授权。 删除、付款、发信、发布、改权限及生产写操作不得因“来自已渲染 App”而自动可信。

MCP Apps 为什么让 XSS 问题重新变得重要

传统 MCP 工具主要返回文本、结构化数据或资源。MCP Apps 增加了交互 UI:工具通过 _meta.ui.resourceUri 指向一个 ui:// HTML 资源,宿主获取资源后在对话内渲染,工具结果再进入该界面。界面还可通过 MCP Apps 的通信协议请求工具、发送消息或更新上下文。

这带来两种信任边界的叠加:第一层是浏览器边界,HTML、CSS、JavaScript 和外部资源可能含主动内容;第二层是 Agent 边界,界面不仅展示信息,还可能间接影响模型上下文和工具执行。普通后台页面里的 XSS 已经危险,而嵌入 AI 客户端的 XSS 还可能利用“用户相信 AI 客户端”的心理,伪造确认按钮、诱导授权或把恶意字符串送回模型。

官方 MCP Apps 文档明确采用沙箱 iframe、预声明模板、可审计 JSON-RPC 和用户同意等多层安全模型。这里要避免一个误读:官方所说的“安全渲染”并不等于 App 开发者可以放心使用 innerHTML。宿主隔离的是 App 与父客户端;App 自身仍需承担正常 Web 应用的 XSS 防护责任。

可继续阅读 AI Stack Nav 的 MCP 安全相关文章 与 AI Agent 安全沙箱教程,把本文放进更完整的工具权限与网络出口治理体系。

三类风险:HTML 注入、Stored XSS 与能力滥用

风险常见数据来源典型危险点Sandbox 能否单独解决首要控制
HTML 注入模型输出、工具结果、用户备注innerHTML、模板字符串不能上下文编码、使用安全 DOM API
Stored XSS工单、知识库、项目描述、评论数据持久化后被多人界面加载不能写入验证、读取编码、富文本清洗
DOM XSSURL、hash、消息事件、客户端状态document.write、insertAdjacentHTML不能安全 sink、消息 schema 校验
跨域资源滥用外部脚本、图片、字体、WebSocket过宽 CSP、通配符域名部分最小 CSP、代理与出口控制
UI 发起工具滥用被攻陷的按钮或脚本tools/call、上下文更新部分宿主授权、风险分级、人工确认
点击劫持/仿冒确认恶意 UI、嵌套 iframe伪造宿主样式与审批按钮部分清晰边界、禁止嵌套 frame、宿主确认

HTML 注入不一定执行脚本,但仍可欺骗用户

攻击者不必成功运行 <script> 才有价值。插入一个伪造的“重新登录”表单、覆盖真实按钮、创建透明点击层或加载跟踪图片,都可能造成凭据诱导、误审批和信息泄露。因此,安全测试不能只检查 alert(1) 是否弹出,还要检查样式覆盖、表单提交、导航、图片回连、SVG 事件和 URL 协议。

Stored XSS 为什么更危险

Stored XSS 的恶意内容先进入数据库、知识库或第三方系统,再在后续会话中被其他用户的 MCP App 加载。攻击可能跨用户、跨时间反复触发,且数据看起来来自“内部可信系统”。例如,客服工单标题、GitHub Issue、CRM 客户名称或监控告警正文都可能成为持久化载体。

在 AI 场景中,模型生成内容也必须视为不可信。模型可能复述攻击者放进文档的 HTML,工具可能把远端字段原样返回,服务器也可能把 Markdown 渲染结果当成安全 HTML。信任应根据数据流而不是“由谁最后返回”决定。

MCP Apps 中 Stored XSS 从不可信数据进入 HTML、跨会话触发并调用宿主能力的攻击链
Stored XSS 攻击链:恶意内容被持久化,经工具结果进入 App DOM,随后尝试利用网络或宿主能力扩大影响。

MCP Apps 的 Sandbox 到底保护什么

官方架构把 View 放进由宿主控制的沙箱 iframe。它的主要价值是让 App 无法直接读取父页面 DOM、Cookie 或本地存储,也不能在父页面 JavaScript 上下文中执行。宿主与 View 之间的交互走 postMessage 承载的 JSON-RPC,因而可以记录、校验或阻断。

但沙箱内部不是“没有 JavaScript”。MCP Apps 本来就需要脚本实现交互,因此规范的 Sandbox Proxy 会在独立来源上承载 View,并实施声明式 CSP。恶意脚本若在 View 内执行,仍可读取 View 当前收到的工具结果、修改 App UI、调用被公开的 SDK 方法,以及访问 CSP 允许的来源。

这意味着安全边界应分为七层:

  1. 数据层: 标记用户输入、远端 API、模型输出和工具结果为不可信。
  2. 渲染层: 默认文本渲染,富文本先清洗,禁止危险 DOM sink。
  3. iframe 层: 宿主使用独立来源与规范要求的 Sandbox Proxy,不自行弱化隔离。
  4. CSP 层: 默认拒绝,逐域放行连接、资源、frame 和 base URI。
  5. 消息层: 校验来源窗口、方法、schema、大小、频率和初始化状态。
  6. 能力层: 对浏览器权限、工具和上下文更新实施最小授权。
  7. 业务层: 对高风险动作增加后端授权、幂等、人工确认、审计和回滚。

不要机械套用普通 iframe 的配置

MDN 提醒:同源 iframe 同时启用 allow-scripts 与 allow-same-origin 可能削弱 sandbox。MCP Apps 规范采用“宿主与 Sandbox 必须不同源”的架构,并由 Sandbox Proxy 加载 View,因此实现宿主时应遵循官方 SDK/规范,不要把第三方 HTML 直接用 srcdoc 塞进与客户端同源的 iframe,也不要自行组合一个看似相同但信任边界不同的沙箱。

安全渲染:从 innerHTML 改成数据到 DOM

工具调用与权限:被攻陷的 UI 不能继承用户全部能力

MCP Apps 可请求摄像头、麦克风、定位和剪贴板写入等浏览器能力;宿主可以选择是否通过 iframe allow 属性授予。App 必须进行特性检测并在权限被拒时优雅降级,不能把“声明 permissions”当成已经获批。

对工具调用建议分三级:

  • 低风险只读: 读取公开数据、重新查询当前面板,可在明确范围内自动执行并限流。
  • 中风险内部操作: 创建草稿、写入测试环境、修改非敏感配置,需要显示工具名、参数摘要和目标环境。
  • 高风险不可逆: 付款、删除、发邮件、发布、改权限、生产写入,必须由宿主提供不可伪造的原生确认界面,并由服务器再次检查身份、权限、资源范围和短时授权。

界面里的自绘“确认”按钮不是安全确认,因为被攻陷的界面可以伪造点击含义。真正的确认必须位于宿主信任域,并展示规范化后的最终参数。

MCP Apps 从不可信数据、渲染、Sandbox、CSP、消息校验到工具授权的七层防御流程
MCP Apps 七层防御闭环:每层解决不同问题,任何单层都不能替代端到端授权与审计。

企业落地:12 步安全实施与验收

以下流程可以直接加入上线清单:

  1. 建立数据流图。 标出 UI 资源、工具结果、模型输出、数据库字段、第三方 API、消息通道与所有网络出口。
  2. 建立污点规则。 默认将外部内容、用户输入、持久化自由文本和模型输出标为不可信,直到在具体输出上下文完成处理。
  3. 搜索危险 sink。 检查 innerHTML、outerHTML、document.write、insertAdjacentHTML、动态脚本、eval、不安全 URL 与模板绕过。
  4. 改为安全 DOM API。 纯文本用 textContent,属性通过类型化 DOM 属性设置,URL 解析后仅允许业务需要的协议。
  5. 集中富文本清洗。 使用维护中的清洗库、最小 allowlist 和固定入口,禁止开发者自行写正则过滤 HTML。
  6. 采用官方 Sandbox Proxy。 宿主与沙箱独立来源,禁止第三方 View 与 AI 客户端共享来源。
  7. 收紧 CSP。 分别审查连接域、资源域、frame 域与 base URI;删除通配符、测试域及不再使用的 CDN。
  8. 最小化浏览器权限。 默认不请求 camera、microphone、geolocation、clipboardWrite;按功能逐项启用。
  9. 验证消息和能力。 使用官方 SDK,限制方法、载荷、频率和生命周期;不把任意消息直接转为工具调用。
  10. 建立宿主侧审批。 高风险工具在可信 UI 中展示最终参数,并由后端重新授权;加入幂等键、超时与可回滚设计。
  11. 自动化安全测试。 对存储字段、工具结果、Markdown、SVG、链接、消息、CSP 违规和拒绝权限场景进行回归测试。
  12. 监控与响应。 记录资源版本哈希、工具名、规范化参数、用户主体、审批结果、网络目标和策略拒绝原因;准备停用资源、撤销令牌及回滚版本的流程。

推荐测试矩阵

测试维度必测用例通过标准
文本渲染<、>、引号、超长文本、Unicode作为文本显示,不改变 DOM 结构
富文本事件属性、SVG、危险 URL、嵌套标签危险节点与属性被移除
持久化攻击字符串写入后由另一账号读取不执行,审计能定位来源记录
CSP未声明 API、脚本、图片、frame浏览器阻断并产生可观测事件
权限摄像头/麦克风/定位被拒功能降级,不绕过、不反复诱导
消息错误 source、未知 method、超大载荷宿主拒绝且不调用工具
工具调用删除、发信、生产写入必须经过宿主确认和服务端授权
回滚新 UI 资源出现异常能按版本快速禁用或回退

测试时只使用隔离环境和无害标记字符串,不要对第三方或生产客户端进行未授权攻击。Stored XSS 回归应验证“内容没有被解释执行”,而不是追求真实数据外传。

成本、性能与可维护性

安全控制会增加少量开发与运行成本,但最昂贵的不是 DOMPurify 或 CSP,而是没有统一渲染组件导致每个 App 重复犯错。建议平台团队提供安全文本组件、富文本组件、链接组件、消息 schema、权限策略和工具确认 API,让业务团队默认走安全路径。

单文件打包可以减少外部依赖和 CSP 配置,但会增加资源体积与更新粒度;外部静态资源便于缓存,却扩大供应链与域名白名单。企业可按风险选择:敏感内部 App 优先单文件和自有域;公共展示 App 可使用固定 CDN,但需要完整性、版本锁定、变更审查和故障回退。

清洗和 schema 校验通常不是性能瓶颈。对于大块日志、富文本或实时流,采用大小上限、分页、虚拟滚动和分段清洗;不要为了性能跳过清洗,也不要把整个原始工具结果长期存入浏览器存储。重试必须有上限和退避,写操作使用幂等键,超时后先查询状态再决定是否重试。

局限、故障排查与应急响应

宿主支持存在差异。MCP Apps 是可选扩展,权限、稳定域名、CSP 展现和确认交互可能因客户端而异;App 应提供文本回退,且不得把关键安全检查只放在前端。服务端必须对每次工具调用执行身份和权限校验。

常见故障可按顺序排查:先看宿主是否协商 MCP Apps 能力,再确认 ui:// 资源、MIME 类型和 _meta.ui.resourceUri;随后检查 CSP 违规、CORS 响应、权限拒绝和初始化握手;最后检查消息 schema 与工具授权。开发时临时放宽 CSP 的配置不得进入生产。

发现疑似 Stored XSS 后,应立即停止分发受影响 UI 版本,禁用高风险 App 能力,保全资源版本、数据库记录、工具调用和网络日志;定位污染数据入口与受影响用户,清洗或隔离历史记录,撤销可能泄露的令牌,并发布经过回归测试的新版本。不要只删除一条 payload 后恢复服务,因为相同 sink 可能还有其他载体。

事实依据与来源

  • 官方已确认: MCP Apps 使用 ui:// 资源、沙箱 iframe 和基于 JSON-RPC 的双向通信;宿主可预取模板并进行安全审查。
  • 官方已确认: MCP Apps CSP 将连接域与静态资源域分开声明;浏览器权限由资源请求,宿主可以选择是否授予。
  • 官方规范要求: Host 与 Sandbox 使用不同来源,Sandbox 对 View 应用声明域名和限制性默认 CSP,并阻断 object-src 等危险能力。
  • OWASP 指导: 不可信数据应使用上下文相关输出编码;确需渲染 HTML 时使用专用清洗库,CSP 只作为纵深防御。
  • 编辑判断: Stored XSS 与 UI 发起工具调用结合后,风险可能从“界面内执行”升级为“利用 Agent 能力执行操作”,实际影响取决于宿主授权和服务端权限设计。
  • 实施建议: 七层防御、三级工具风险与 12 步验收流程是本文根据官方机制整理的工程方案,并非 MCP 官方强制分级。

内容核验日期:2026 年 09 月 23 日。 具体宿主实现、SDK 版本与扩展能力可能继续变化,上线前应重新核对官方规范和目标客户端文档。

FAQ

MCP Apps 的 HTML 默认就是安全的吗?

不是。宿主提供的沙箱能隔离父客户端,但 HTML 内部仍可能发生 XSS。App 开发者必须对工具结果、数据库内容、模型输出和消息数据实施安全渲染、清洗、CSP 与权限控制。

iframe Sandbox 能彻底防住 Stored XSS 吗?

不能。它通常能阻止恶意脚本读取父页面 Cookie 或 DOM,却不能阻止脚本读取 App 已收到的数据、篡改 App 界面或请求 App 被允许的工具和网络能力。Sandbox 是影响面控制,不是 XSS 修复。

所有动态内容都应该使用 textContent 吗?

纯文本应优先使用 textContent。只有确实需要富文本时才使用 innerHTML,而且输入必须经过维护中的 HTML 清洗库和最小 allowlist;清洗后不得再次进行不安全拼接。

CSP 配好了,还需要 DOMPurify 吗?

需要。CSP 可能因配置错误、受信任域被攻陷或浏览器差异而失效,且不能解决所有 HTML 欺骗。OWASP 将 CSP 视为纵深防御;安全 sink、输出编码和 HTML 清洗仍是主要控制。

MCP App 可以直接访问外网吗?

取决于宿主和资源声明。应用需要在 _meta.ui.csp.connectDomains 中声明 fetch、XHR 或 WebSocket 的目标来源,目标服务器还可能要求正确 CORS。企业环境应再叠加网关和网络出口策略。

permissions 声明后就一定能使用摄像头或麦克风吗?

不一定。官方接口把它定义为请求,宿主可以不授予。应用必须进行特性检测,提供拒绝后的降级路径,且不应在无明确功能需要时请求敏感权限。

UI 内的确认按钮能用于批准删除或付款吗?

不能作为最终安全确认。被攻陷的 UI 可以伪造按钮和参数。删除、付款、发信、发布或生产写入应由宿主可信界面展示最终参数并确认,服务端随后再次检查用户身份和权限。

如何发现历史数据中的 Stored XSS 风险?

先盘点所有自由文本和富文本字段,再追踪它们进入 App DOM 的路径;用静态扫描查危险 sink,用隔离账号加载历史记录做回归,并记录 DOM 变化、CSP 违规、网络请求和工具调用。不要在生产中使用可执行攻击代码。

不支持 MCP Apps 的客户端怎么办?

工具应提供有意义的文本或结构化数据回退。MCP Apps 是渐进增强而不是必需能力,服务端可根据能力协商注册或返回 UI,同时保证核心操作仍能通过普通 MCP 结果完成。

参考来源

  1. MCP Apps 官方概览
  2. MCP Apps 构建教程
  3. MCP Apps CSP 与 CORS 官方文档
  4. SEP-1865:MCP Apps 交互式 UI
  5. MCP Apps 2026-01-26 规范
  6. MCP UI 权限接口
  7. OWASP XSS Prevention Cheat Sheet
  8. MDN iframe sandbox 安全说明
  9. MDN Window.postMessage

内容核验日期:2026 年 09 月 23 日

工具评测文章

从工具选型到任务练习

先确认工具适合自己的任务,再通过学习路径完成免费练习。

AI 工具库 按分类浏览工具介绍与相关教程,先确认工具是否适合你的任务。 查看详情 三条任务学习路径 查看三条任务路径的教程与免费练习,按任务核对资料目录和适用条件。 查看详情

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

本站累计访问量: 406,324 次
AI Stack Nav 客服会员 / 支付 / 下载 / 工具库
你好,我是 AI Stack Nav 客服助手。你可以问我会员开通、微信支付、资料下载、订单入口、AI 工具库等问题。