恶意CDN仍潜伏GitHub Pages,AI让情况恶化
The Malware CDN is Still Lurking in GitHub Pages, and AI Just Made It Worse
UC Berkeley研究人员发现,近2000个GitHub Pages站点(18000+页面,累计530K+星标)仍在加载来自polyfill.io及其关联恶意CDN的脚本。这些CDN由已被OFAC制裁的Funnull Technology Inc.(现更名Triad Nexus)运营,2024年被出售后开始条件性注入恶意载荷,劫持移动用户、跳转欺诈站点、伪造认证弹窗窃取凭证。扫描12000+站点确认786个加载polyfill.io,1191个加载其他Funnull CDN。更严峻的是,所有测试的大语言模型在生成前端代码时仍推荐这些被污染的CDN URL,包括CyC2018/CS-Notes(184K⭐)、microsoft/AirSim(18K⭐)等知名项目及多所大学课程页面。
polyfill.io等恶意CDN仍在GitHub Pages上感染近2000个站点,更可怕的是所有测试的AI模型都还会推荐这些链接,AI编码的便利正在变成供应链投毒的加速器。
Hao Wang、Koushik Sen、Dawn Song
你的 AI 编程助手正在悄悄植入一条供应链后门。在 polyfill.io 被出售给一个后来遭到制裁的运营者并变成一个恶意软件 CDN 一年之后,近 2,000 个仍在线的 GitHub Pages 站点(18,000+ 个页面,合计 530K+ stars)依然从该网络加载脚本。而 AI 让情况更糟:我们测试的每一个 LLM 在生成前端代码时,仍然会推荐这些已被攻陷的 CDN URL。
一天下午,我打开了自己的个人网站(很随意,我知道)。意想不到的事情发生了:弹出了一个灰色弹窗,要求输入用户名和密码。这是 nginx 的认证对话框,所以也许很正常——只不过我的网站根本没有 nginx 认证。那它到底是从哪来的?
困惑了几分钟后,我找到了罪魁祸首。HTML 深处埋着一个我甚至不知道其存在的单个 <script src="https://polyfill.io/..."> 标签。但修复很简单:删掉这个标签,重新构建,推送。问题解决。
一周后,我在浏览一位顶尖 AI 研究者的个人网站。你猜怎么着——同样的灰色弹窗出现了。同样的认证窗口,同样的 polyfill.io 指纹。

我们俩都毫不知情。我们运行的是来自一个 CDN 运营者的代码,而美国海外资产控制办公室(OFAC)已在数月前因一起臭名昭著的恶意软件事件对其施加了制裁。幸运的是,该脚本当时已不再注入任何恶意内容。如果当时存在任何恶意代码,仅仅在本地运行一次该网站,或者仅仅点击一次该网站,都可能给我们或其他研究者的电脑带来难以估量的安全问题。
这引出了一个我无法释怀的问题:还有多少人受到影响却毫不知情?而为什么连一名安全研究员都会在毫无察觉的情况下落入这个陷阱?
一个合法服务如何变成恶意软件分发网络
要理解这些问题,我们必须先了解什么是 polyfill.io。
近十年来,polyfill.io 一直是前端开发领域广受认可的服务。一个 polyfill 脚本标签就能让使用较旧浏览器的访客正常渲染你的网站。它出现在教程、样板代码仓库和 Stack Overflow 回答中多达数百万次。
2024 年初,该域名被出售给 Funnull Technology Inc.。几周之内,该服务便开始有条件地在其提供的脚本中注入恶意载荷——针对移动端用户、重定向至诈骗网站,并叠加伪造的身份验证提示以窃取凭证。由于注入仅在特定条件下触发(浏览器不对、一天中的时段不对、首次访问),许多网站所有者从未察觉。
polyfill.io 最终被证明只是一个更大网络中最为显眼的部分。Sansec 和 Censys 的安全研究人员发现,Funnull 使用相同的 Cloudflare 账户凭证运营着多个热门 CDN——相同的基础设施,相同的运营者:
| 域名 | 证据 |
|---|---|
bootcss.com | 直接:恶意重定向载荷被解码并公开(2023 年 6 月) |
polyfill.io | 直接:在野捕获的恶意载荷(2024 年) |
bootcdn.net | 间接:同一 Cloudflare 账户;被 Google 在广告主警告中点名 |
staticfile.org / .net | 间接:同一 Cloudflare 账户;同一运营者 |
2025 年 5 月,OFAC 对 Funnull Technology Inc. 实施制裁,该公司随即更名为 Triad Nexus。其 CDN 域名仍保持在线。此后研究人员又识别出新一代前端——cdn1.ai、bolecnd.com、yunray.ai——评估为截至 2025 年 6 月已上线的 Funnull 别名。
结论:这五个 CDN 都不应被信任。
扫描 12,000 多个 GitHub Pages 站点揭示了什么
为什么是 GitHub Pages?
GitHub Pages 已成为学术个人网站、课程页面、开源文档、项目演示和开发者作品集的默认托管选择之一。它免费、易于搭建、与 GitHub 仓库紧密集成,并提供便捷的 github.io 域名,无需用户自行管理托管基础设施。正是这种便利性,使其在学术界和开源社区中被如此广泛地采用。
但同样的便利也制造了一个安全盲区。网站一旦部署,便可在几乎无需维护的情况下持续提供内容多年。一个最后更新于 2021 年的仓库,到 2026 年可能仍在托管着一个活跃的网站——而每一位访客仍然会加载原始开发者所包含的那些 script 标签。
我们搜索了什么
我们在 polyfill.io、bootcss.com、bootcdn.net、staticfile.org 和 staticfile.net 上进行了扫描,覆盖了已识别出的整个 Funnull CDN 家族。
我们检索了从 GitHub Code Search 和 Sourcegraph 获取的 GitHub Pages。我们通过源代码确认了感染,并通过对网站上所有页面进行实时爬取,验证了这些恶意 CDN 的存在。
我们发现了什么
| 指标 | Polyfill | 其他 Funnell CDN |
|---|---|---|
| 有提及的站点 | 4,634 | 7,955 |
| 源代码被感染的站点 | 3,000 | 2,306 |
| 正在主动加载恶意软件的站点 | 786 | 1,191 |
| 活跃站点中被感染的页面总数 | 4,228 | 14,156 |
令人震惊。1,960 个站点和 18,384 个页面仍处于感染状态。受害者不仅仅是无人知晓的个人作品集。受影响的页面平均拥有 271 颗星,其中 66 个仓库超过 1K 颗星。受影响页面的星标总数超过 530K。
这些受影响的页面包括
- CyC2018/CS-Notes(184K ⭐):一份技术面试参考资料
- hollischuang/toBeTopJavaer(25K ⭐):一份 Java 职业指南
- microsoft/AirSim(18K ⭐):微软开源的一款无人机与自动驾驶车辆模拟器
- 来自 UC Berkeley、Harvard、KU Leuven 的课程页面
- 以及许许多多其他内容
该存档中的每一个页面都服务于同一个恶意域名。
为什么有了 AI,这种情况会变得更糟
如今人人都在用 AI 处理前端杂活。然而,每个大语言模型都或多或少学到了 https://cdn.polyfill.io/v3/polyfill.min.js 是加载浏览器 polyfill 的标准方式。这一建议出现在数百万条 Stack Overflow 回答、博客文章和教程仓库中。它作为正确做法被烙进了训练数据。
我们直接对此进行了测试。我们向四个模型发送了四个贴近真实的代码生成提示词:Moonshot Kimi K2.7 Code、Meta Llama 3.3 70B、Qwen 2.5 7B,以及通过 Claude Code CLI 调用的 Opus4.8。这四个提示词覆盖了开发者真实工作流中可能出现的场景:用 MathJax 构建学术页面、修复浏览器兼容性、生成作品集,以及编写一个使用 CDN 镜像的页面。
| 模型 | 不安全 | 出现的域名 |
|---|---|---|
| Llama 3.3 70B | 4 / 4 | polyfill.io、staticfile.org |
| Kimi K2.7 Code | 3 / 4 | polyfill.io、bootcdn.net、staticfile.org |
| Qwen 2.5 7B | 1 / 4 | polyfill.io |
| Opus 4.8 | 1 / 4 | bootcdn.net |
最引人注目的数字:所有模型都至少返回了一个由 Funnull 运营的域名。
这不仅仅是模型幻觉问题。这些 URL 是真实存在的。代码可以运行。生成的页面可能正常渲染。从模型的角度来看,它已经给出了一个看似合理的答案。
问题在于,训练数据底下的世界已经变了。一个在 2019 年还安全的依赖,到了 2024 年可能变得危险。一个曾出现在成千上万篇教程里的 CDN,之后可能易主。一个曾经代表兼容性的 script 标签,可能变成每个访客浏览器里的远程代码执行入口。
AI 编程助手尤其容易放大这一类 bug,因为输出看起来平平无奇。没有语法错误。没有失败的测试。没有构建中断。开发者在审查生成的 HTML 时,可能看到一个眼熟的 CDN URL 就略过了。在很多情况下,开发者甚至根本不知道模型添加了这个依赖。
软件供应链风险不仅仅关乎你安装的软件包。它还关乎你的代码所信任的 URL。静态网站感觉上像是惰性的,但它们的依赖是活的。
该怎么做,以及下一步
我们建议在你的源代码和生成的站点输出中搜索已识别出的那些 CDN URL。一个简单的例子:
grep -RInE 'polyfill\.io|polyfill\.com|polyfill\.cn|bootcss\.com|bootcdn\.net|staticfile\.org|staticfile\.net' .
如果你找到了匹配项,不要只是修补你碰巧注意到的那一个源文件。检查你的模板、主题、生成的 HTML、归档页面、vendored 资源以及文档构建产物。静态站点生成器可能会在你从某个页面移除同一个标签之后,又把它重新引入。
建议的修复措施:
- 彻底移除 polyfill.io,如果你并不需要它。现代浏览器已支持这些脚本最初用于修补的绝大多数功能。
- 替换不安全的 CDN 链接,改用可信的替代方案,例如
cdn.jsdelivr.net、cdnjs.cloudflare.com、unpkg.com,或自托管资源。 - 尽可能使用子资源完整性(Subresource Integrity)。SRI 哈希允许浏览器在字节发生意外变化时拒绝加载该脚本。
- 审查你的内容安全策略(Content-Security-Policy)。受影响的域名不应出现在
script-src、connect-src或其他允许列表中。 - 审计 AI 生成的 HTML,在发布之前。把编码助手建议的 CDN URL 当作依赖项,而不是无害的样板代码。
我们还发布了一个小型扫描器,可自动检查某个网站是否仍在加载这些域名。你可以输入一个 URL,该工具会爬取该站点、检查脚本来源,并报告是否发现对受影响 CDN 家族的引用。
来源:Berkeley RDI:Blog(AI 安全与评测) · rdi.berkeley.edu