Synth Daily

我们通过供应链攻击拿下了 X、Vercel、Cursor 和 Discord

一名 16 岁的黑客发现,AI 文档平台 Mintlify 存在一个严重的跨站脚本 (XSS) 漏洞。这个单一平台的安全缺陷,演变成了一场波及数百家公司的供应链攻击,包括 X (Twitter)、Vercel 和 Discord 等知名企业。攻击者可以通过一个恶意链接,在这些公司的官方文档页面上执行脚本,从而窃取用户凭证。该漏洞最终被负责任地披露并修复,发现者团队共获得了约 11,000 美元的漏洞赏金。

新的发现:从 Discord 文档更新开始

故事始于 Discord 宣布将其开发者文档平台切换到一个由 Mintlify 驱动的 AI 新平台。作为一名经验丰富的 Discord 漏洞猎人,作者立刻对这个新变化产生了兴趣,并开始研究其实现方式。

Mintlify 是一个能将 Markdown 文档转换成现代化网站的平台。它的一个关键技术特征是,所有使用其服务的网站(无论是托管在 mintlify.app 子域名还是自定义域名上)都必须开放一个名为 /_mintlify/ 的路径,用于支持平台的核心功能。

寻找漏洞:两条线索

作者最初的目标是找到一种方法,通过 Discord 的域名来加载另一个 Mintlify 文档的内容,从而实现攻击。在尝试了路径遍历等方法失败后,他将注意力集中在 /_mintlify/ 路径下的 API 接口上。

  • 失败的尝试:/markdown/ 接口

    • 作者发现了一个名为 /_mintlify/_markdown/_sites/[subdomain]/[...route] 的接口。
    • 这个接口存在缺陷:它没有验证当前访问的域名和请求的子域名是否匹配,这意味着可以在 Discord 的域名下请求任意其他 Mintlify 文档的内容。
    • 然而,这个接口只返回纯文本格式的 Markdown,无法被浏览器渲染成 HTML,因此 无法执行任何脚本,攻击失败。
  • 突破口:/static/ 接口

    • 经过一番探索,作者通过分析 Mintlify 的命令行工具 (CLI) 源码,找到了另一个类似的接口:/_mintlify/static/[subdomain]/[...route]
    • 这个接口同样存在域名验证缺陷,但它用于返回静态文件,而不是 Markdown 文本。

关键的利用方式:恶意的 SVG 文件

作者发现,虽然该静态文件接口限制了 HTML 或 JavaScript 文件的加载,但它允许加载 SVG 图片文件。这是一个决定性的突破。

对于安全研究人员来说,一个常识是:SVG 文件内部可以嵌入 JavaScript 脚本。当这个 SVG 文件被直接在浏览器中打开时,其中的脚本就会执行。

作者立即创建了一个含有恶意脚本的 SVG 文件,并将其上传到自己的 Mintlify 文档中。随后,他通过 Discord 的域名访问了这个文件,脚本成功执行。这证实了一个严重的跨站脚本 (XSS) 漏洞的存在。

合作、报告与修复

由于在 Discord 上发现 XSS 漏洞极为罕见,作者将此发现分享给了朋友,结果发现他们也在独立研究 Mintlify 的安全问题。团队合作由此展开。

他们迅速向 Discord 和 Mintlify 报告了该漏洞。

  • Discord 的反应: 极其重视,立即关闭了整个开发者文档中心长达两小时,并最终回滚到了旧的文档平台。
  • Mintlify 的反应: 在接到通知后很快与团队取得联系,并成立了专门的 Slack 频道,与工程团队合作,迅速修复了这个漏洞以及团队发现的其他安全问题。

影响与结论

这次供应链攻击的影响范围非常广泛,几乎波及了所有使用 Mintlify 的客户。

  • 受影响的公司包括:
    • X (Twitter)
    • Vercel
    • Cursor
    • Discord
    • 以及其他数百家公司。

由于这些公司将文档托管在自己的主域名上,该漏洞使得攻击者仅用一个恶意链接,就有可能实现对用户账户的完全接管

幸运的是,我们负责任地发现并披露了这一漏洞,但这是一个典型的例子,说明了攻破单一供应链可能导致多米诺骨牌式的连锁问题

最终,发现漏洞的团队因此获得了总计约 11,000 美元的漏洞赏金。