bug: Rich UI `input:prompt:submit` silently dropped for `srcdoc` tool-result iframes (opaque origin)

该问题发生在 Open WebUI 的自托管部署环境中。当使用 Rich UI 功能开发工具(Tool),工具返回 `HTMLResponse`,并且该响应通过 `srcdoc` 属性嵌入到 iframe 中时,通过 `window.parent.postMessage` 发送的 `input:pr

bug: Rich UI `input:prompt:submit` silently dropped for `srcdoc` tool-result iframes (opaque origin)

bug: Rich UI `input:prompt:submit` silently dropped for `srcdoc` tool-result iframes (opaque origin)

快速结论:当 Open WebUI 的 Rich UI 工具返回 `HTMLResponse`,并通过 `srcdoc` 渲染 iframe 时,`postMessage({type:’input:prompt:submit’}, …)` 会被静默丢弃,不会触发确认对话框。优先排查 iframe 的 `sandbox` 属性是否缺少 `allow-same-origin` 以及 `iframeSandboxAllowSameOrigin` 设置是否启用。

问题场景

该问题发生在 Open WebUI 的自托管部署环境中。当使用 Rich UI 功能开发工具(Tool),工具返回 `HTMLResponse`,并且该响应通过 `srcdoc` 属性嵌入到 iframe 中时,通过 `window.parent.postMessage` 发送的 `input:prompt:submit` 消息无法被主界面接收,导致用户点击“发送结果到模型”按钮后无任何反应。这是 `HTMLResponse` 工具默认且最常见的渲染路径。

报错原文

window.parent.postMessage({ type: 'input:prompt:submit', text: 'summary...' }, '*');
const isSameOrigin = event.origin === window.origin; // false — opaque origin is "null"
const isTrusted = isSameOrigin || ($settings?.iframeSandboxAllowSameOrigin ?? false); // false by default
if (promptTypes.includes(type) && !isTrusted) return; // ← dropped here

原因分析

根本原因:当 iframe 使用 `srcdoc` 属性且未设置 `allow-same-origin` 时,该 iframe 的 origin 是透明的(opaque origin),即 `event.origin === “null”`。Open WebUI 的 `onMessageHandler` 函数(位于 `Chat.svelte`)只会信任 同源(same-origin)的消息源,或者当用户显式启用 `iframeSandboxAllowSameOrigin` 设置时才会信任。由于 Open WebUI 自身创建的 `srcdoc` iframe 既不是同源,也不属于用户配置的信任源,因此所有 `input:prompt:submit` 类型的消息在到达确认对话框逻辑之前,就被安全网关直接丢弃了。

此问题是 PR #22908(安全修复 GHSA-3vv5-8xxp-4f55)的意外副作用:该修复为了防止外部源绕过确认对话框,添加了 origin 检查,但误伤了自己生成的合法 `srcdoc` iframe。

可能原因:`iframeSandboxAllowSameOrigin` 设置为 `false`(默认值),或者 iframe 的 `sandbox` 属性中未包含 `allow-same-origin`。

环境排查

  • Open WebUI 版本(Issue 关闭于 2026-07-10)
  • 检查工具(Tool)的响应类型是否为 `HTMLResponse`,且 `Content-Disposition` 是否为 `inline`
  • 检查浏览器控制台(Console)是否有任何错误或警告信息
  • 确认 `iframeSandboxAllowSameOrigin` 设置项(位于用户设置或管理面板)是否为默认值 `false`
  • 检查 iframe 的 `sandbox` 属性是否包含 `allow-same-origin`,如:`sandbox=”allow-scripts allow-popups allow-downloads allow-same-origin”`

解决步骤

  1. (可优先尝试)临时缓解方法:在 Open WebUI 设置中启用 iframeSandboxAllowSameOrigin。注意:这会绕过确认对话框直接提交,在多用户部署场景下存在安全风险。
  2. 开发者修复:修改 Open WebUI 源码,将信任锚点从 origin 字符串比较改为 Window 对象身份验证。具体做法是:
    1. FullHeightIframe.svelte 中,在现有的 onLoad 处理函数中暴露一个 onIframeReady 回调,传入 Window 对象。
    2. Chat.svelte(或一个共享 Store)中维护一个 Set<Window> 来存储可信的 contentWindow
    3. onMessageHandler 中添加第三个信任路径:const isOwnEmbed = trustedContentWindows.has(event.source);,当 isOwnEmbedtrue 时,放行消息进入确认对话框逻辑。
  3. 等待官方合并:查看 Pull Request #26914 的状态。该 PR 已标记为“在 dev 分支中修复”(fixed in dev),预计将在后续版本发布。建议升级到包含该修复的版本。

验证方法

创建一个返回 `HTMLResponse` 且包含以下 JavaScript 的测试工具:


// 在 iframe 内部
document.getElementById('submitBtn').addEventListener('click', () => {
  window.parent.postMessage({ type: 'input:prompt:submit', text: '测试摘要...' }, '*');
});

执行该工具并点击按钮后,应该出现“确认来自嵌入内容的提示”(Confirm Prompt from Embed)对话框。如果修复成功,点击按钮后对话框会正常弹出。

参考来源

open-webui/open-webui #26912

open-webui/open-webui #26914

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

celebrityanime
celebrityanime
文章: 12495

发表回复

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