博客遭遇 CDN 供应链投毒攻击:排查与修复全记录

最近发现博客在手机上浏览时会自动跳转到第三方诈骗网站,经过排查发现是使用的 CDN 遭受了供应链投毒攻击。本文记录整个排查和修复过程。

问题现象

  • 手机浏览博客时,页面会自动跳转到诈骗网站
  • 主要影响移动端用户
  • PC 端偶尔也会出现跳转

问题根因

cdn.staticfile.net 供应链攻击

经过排查,发现博客使用的 cdn.staticfile.net2024 年遭受供应链攻击,这是一起与 Polyfill.io 相关的大规模攻击事件。

攻击者通过控制 CDN 源,在 JavaScript 文件中注入恶意代码,将用户(特别是移动端用户)重定向到诈骗网站。

受影响的 CDN 包括:

  • cdn.staticfile.net
  • bootcdn.net
  • polyfill.io
  • 其他多个国内 CDN

本博客受影响的资源

资源 原 CDN 风险
Highlight.js cdn.staticfile.net ⚠️ 高危
Font Awesome cdn.staticfile.net ⚠️ 高危
MathJax cdn.staticfile.net ⚠️ 高危
Google Fonts fonts.loli.net ⚠️ 中危

修复方案

1. 替换被投毒的 CDN

将所有 cdn.staticfile.net 替换为安全可靠的 CDN:

- https://cdn.staticfile.net/highlight.js/11.7.0/highlight.min.js
+ https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js

- https://cdn.staticfile.net/font-awesome/6.4.0/css/all.min.css
+ https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css

- https://cdn.staticfile.net/mathjax/3.2.2/es5/tex-mml-chtml.js
+ https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js

2. 智能字体 CDN 切换

为了兼顾国内外用户,实现了智能字体 CDN 切换:

用户 CDN
国内 google-fonts.mirrors.sjtug.sjtu.edu.cn
国外 fonts.googleapis.com

实现逻辑

  1. 检查 localStorage 缓存(7 天有效期)
  2. 无缓存时优先尝试国内 SJTUG 镜像
  3. 加载失败自动回退到 Google Fonts
  4. 最后一天后台静默刷新缓存

其他优化

在排查过程中,顺便修复了以下问题:

暗色模式闪烁 (FOUC)

问题:切换页面时先显示白色背景再变暗

原因localStorage.getItem('theme') 可能返回 'auto',但 CSS 只识别 'light'/'dark'

修复:在 <head> 中立即计算有效主题值:

const saved = localStorage.getItem("theme") || "auto";
const systemPrefersDark = window.matchMedia(
  "(prefers-color-scheme: dark)"
).matches;
const effective =
  saved === "auto" ? (systemPrefersDark ? "dark" : "light") : saved;
document.documentElement.setAttribute("data-theme", effective);

首页无限滚动失效

问题:滚动到底部无法加载更多文章

原因search.json 路径缺少 /blog 前缀,在 GitHub Pages 上 404

修复

- fetch('/search.json')
+ fetch(basePath + '/search.json')  // basePath = '/blog'

移动端 Hover 残留

问题:移动端 TOC 和菜单触摸后高亮不消失

原因:触摸屏的 :hover 状态会持续保持

修复:使用 @media (hover: hover) 只在支持鼠标悬浮的设备上应用 hover 效果

经验教训

  1. 不要盲目使用国内 CDN:很多所谓的"加速"镜像站安全性堪忧
  2. 定期检查第三方依赖:特别是 CDN 和 npm 包
  3. 优先使用官方 CDN:如 cdnjs.cloudflare.com、cdn.jsdelivr.net
  4. 移动端测试:供应链攻击往往只针对移动端用户

有想法?欢迎通过邮件讨论。

目录