我刚刚追踪到了嵌入插件出现此问题的根源。在配置嵌入时,有一个“允许的主机”(Allowed Hosts)设置,该设置会相应地设置 iframe 的内容安全策略(CSP),导致 iframe 仅能在该主机上显示。例如,如果我将嵌入配置为允许的主机为 example.com,然后尝试在 attacker.com 上嵌入 JS,iframe 将拒绝加载,并报错:
拒绝加载 'https://forum.example.com/' 的框架,因为祖先元素违反了以下内容安全策略指令:"frame-ancestors 'self' https://example.com"。
然而,此时 JS 实际上已经运行,并使用提供给嵌入代码的任意 URL 在论坛上创建了一个主题。
在我的情况下,问题在于我们使用 Netlify 来预览构建,因此博客的副本实际上是从 netlify.app 的 URL 提供服务的。该服务加载了 embed.js,并为之前错误导入的帖子创建了论坛线程。
这不一定是一个安全问题,因为它仍然只能为配置网站上的 URL 创建主题,且这些 URL 必须符合路径白名单。但这对当前的迁移策略来说是个问题,因为在将旧帖子迁移到 Discourse 时,我无法为论坛主题设置 embed_url。
修复方法是添加一条 CSP 规则,防止 embed.js 在“允许的主机”设置中未配置的任何域名上运行。
作为概念验证,我将嵌入代码复制到一个完全无关的域名,并将 discourseEmbedUrl 设置为其中一个我导入的旧帖子。加载页面后,iframe 被阻止了,但 JS 已经运行并创建了论坛线程。
如果您认为这更偏向于安全问题而非普通漏洞,我很乐意删除此帖子,并通过 HackerOne 进行报告。