
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”`
解决步骤
- (可优先尝试)临时缓解方法:在 Open WebUI 设置中启用
iframeSandboxAllowSameOrigin。注意:这会绕过确认对话框直接提交,在多用户部署场景下存在安全风险。 - 开发者修复:修改 Open WebUI 源码,将信任锚点从 origin 字符串比较改为
Window对象身份验证。具体做法是:- 在
FullHeightIframe.svelte中,在现有的onLoad处理函数中暴露一个onIframeReady回调,传入Window对象。 - 在
Chat.svelte(或一个共享 Store)中维护一个Set<Window>来存储可信的contentWindow。 - 在
onMessageHandler中添加第三个信任路径:const isOwnEmbed = trustedContentWindows.has(event.source);,当isOwnEmbed为true时,放行消息进入确认对话框逻辑。
- 在
- 等待官方合并:查看 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)对话框。如果修复成功,点击按钮后对话框会正常弹出。


![[问与答] codex 的重置卡过期是废弃还是自动重置一次](https://www.chat-gpts.plus/wp-content/uploads/2026/07/ai_cover_4-335-768x403.jpg)
