al-folio v1.1 版本解析:插件生态首轮安全加固、缺陷修复与精确版本升级指南
2026/9/14 5:04:15 网站建设 项目流程

al-folio v1.1 版本解析:插件生态首轮安全加固、缺陷修复与精确版本升级指南

【免费下载链接】al-folioA beautiful, simple, clean, and responsive Jekyll theme for academics项目地址: https://gitcode.com/GitHub_Trending/al/al-folio

v1.1 是 al-folio 在 v1 插件架构上的第一个维护版本(maintenance release),核心内容是安全与缺陷修复,同时标志着插件生态正式开始对外发布——所有积压待发布的 gem 全部发布,发布流程由人工转为自动化。本文以 docs/releases/v1.1.md 为主体,结合本仓库 Gemfile、_config.yml、docs/ARCHITECTURE.md 等源码与文档,完整梳理 v1.1 的三处真实漏洞、八项缺陷修复与多项改进,并给出可直接照做的精确升级步骤。读完本文,你将掌握如何在 v1 插件架构下安全地从 v1.0 升级到 v1.1,以及如何用al-folio upgrade auditbundle list验证修复是否真正生效。


一、v1.1 版本定位:插件生态的第一次正式发布

在 v1.1 之前,al-folio 已经完成了从"单体主题"到"薄启动器(thin starter)+插件 gem"的 v1 架构迁移:本仓库只保留启动接线(Gemfile_config.yml_data/featured_plugins.yml)、示例内容与跨插件集成测试,而所有运行时(布局、includes、Sass、Liquid 标签/过滤器、特性 JS)都托管在独立发布、独立版本号的 gem 中,详见 docs/ARCHITECTURE.md。

v1.1 的绝大部分用户可见变化发生在这些 gem 内部,而不是本仓库。它是插件生态真正开始发货的版本:此前多个 gem 在main分支上已有修复却从未发布,v1.1 起全部 16 个插件仓库接入了 tag 驱动的release.yml自动化发布流水线。

1.1 v1.1 的插件版本清单

本次发布,启动器的Gemfile将各插件从 v1.0 精确锁定到 v1.1 版本:

gemv1.0v1.1
al_folio_core1.0.101.0.12
al_folio_cv1.0.01.0.2
al_folio_distill1.0.21.0.3
al_analytics1.0.01.0.2
al_ext_posts1.0.11.0.3
al_img_tools1.0.21.0.3
al_search1.0.21.0.3
al_math1.0.11.0.2

对照当前仓库的 Gemfile(group :al_folio_plugins),可以看到后续 v1.2 又进一步推进:al_folio_core已到 1.0.15,并新增了al_email_protectal_marimoal_rtl等新插件。v1.1 正是这条插件版本演进线上承上启下的关键一环。

1.2 关键警告:bundle update不会自动升级

这是 v1.1 升级中最容易踩的坑。由于Gemfile对每个插件都使用精确版本号(= 1.0.x)固定,Bundler 会忠实遵守你Gemfile里已有的 pin——因此一个 v1.0 站点执行bundle update后会停留在有漏洞的版本上,且不报任何错误。必须先手动修改 pin,才能完成升级。

这正是 docs/ARCHITECTURE.md 中描述的"无报错静默失败"模式在版本管理上的体现:Gemfile_config.yml是两张必须一致的表,任何一处单独变更都不会生效。


二、🔒 安全修复:三个影响所有 v1.0 站点的真实漏洞

v1.1 修复的三个漏洞都影响每一个v1.0 站点,属于必须升级的硬性原因。

2.1 Swiper 原型污染 —— CVSS 9.4(al_img_tools1.0.3)

  • 漏洞编号:CVE-2026-27212 / GHSA-hmx5-qpq5-p643,影响 Swiper>= 6.5.1, < 12.1.2
  • 影响范围:v1.0 附带的 Swiper 版本为 11.0.5,处于受影响区间。
  • 修复方式:将 Swiper 升级到 12.1.2,并同步刷新 CSS、JS 及 source map 的 SRI(Subresource Integrity)哈希。
  • 兼容性:图片轮播使用swiper-elementWeb Component 包,其<swiper-container>API 在主版本升级前后保持一致,因此模板无需任何改动

2.2 移除 polyfill.io —— 供应链攻击路径(al_math1.0.2)

  • 背景:polyfill.io CDN 在 2024 年 6 月被供应链攻击者接管,曾被用于分发恶意负载。
  • 技术事实:MathJax 3 在 al-folio 支持的所有浏览器上都不需要 polyfill.io,该<script>标签纯属多余且危险。
  • 修复方式:直接从 MathJax 加载路径中删除该脚本标签。作为后续清理,v1.1 同时移除了_config.yml中已经没有任何代码读取的third_party_libraries.polyfill死配置项。

2.3 Distill 运行时不再从无完整性校验的第三方源加载(al_folio_distill1.0.3)

这是三处漏洞中机制最复杂的一个,值得展开说明:

  • 漏洞机制:打包进 gem 的transforms.v2.js携带了上游的Polyfillstransform,该 transform 会移除页面本地的template.v2.js标签,然后从硬编码的https://distill.pub/template.v2.js重新注入——不带任何 SRI 完整性校验。这等于静默丢弃了 gem 特意用哈希 pin 住的副本,并把每个 Distill 页面的任意 JS 执行权拱手让给该源的持有者。
  • 修复方式:运行时改为从 gem 内置(vendored)副本提供服务,integrity固定到provenance.json中提交的摘要;同时增加构建期检查,把"漂移"上报为构建告警,而不是让它在访问者浏览器里直接触发 SRI 失败。
  • 远程加载改为显式开关:新增al_folio.distill.allow_remote_loader配置项,默认falsesync_distill.sh在将来重新同步时若再次引入远程加载器,会以非零退出码失败。
  • 存量站点注意事项:如果你的_config.yml仍写着al_folio.distill.allow_remote_loader: true,请改为false。在 1.0.2 中该开关是无效的(inert);在 1.0.3 下保持true等于主动退出本次加固保护。bundle exec al-folio upgrade audit会把它报告为blocking(阻塞级)发现项。

当前仓库的 _config.yml 已体现该开关的最新状态:al_folio.distill.allow_remote_loader: false


三、🐛 缺陷修复:从仓库卡片空白到移动端子菜单越界

v1.1 的缺陷修复分布在多个 gem 中,按 gem 维度梳理如下。

3.1 仓库卡片完全空白(al_folio_core1.0.12)

该问题有两个叠加的根因:

  1. 上游服务不可靠:公共的github-readme-stats.vercel.app实例长期不稳定,默认值已切换到 API 兼容、持续维护的github-stats-extended.vercel.app分支——既有查询参数全部继续可用
  2. 服务 URL 相对路径化:服务 URL 之前直接从site.external_services.*插值,从模板生成但缺少该配置块的站点会输出相对路径/api/pin/?…,导致所有卡片无论上游是否健康都 404。现在通过default:回退兜底,同时仍可通过配置覆盖以支持自托管

对照当前 _config.yml 的external_services块,可以看到github_readme_stats_url已默认指向https://github-stats-extended.vercel.app,并保留了github_profile_trophy_url的可覆盖入口。

3.2 移动端子菜单渲染到屏幕外(al_folio_core1.0.12)

  • 现象:折叠的导航栏内部,下拉菜单继承了基础 Tailwind 规则中的position: absoluteright: 0,被锚定到视口左边缘之外(在 393px 屏幕上实测left: -85.7px)。
  • 修复:在sm断点以下,菜单改为静态定位、左对齐、允许长条目换行,并撑满整个导航栏宽度。
  • 参考:对应 issue #3663。

3.3 链接预览无图片(al_folio_core1.0.12)

  • 现象og:imagetwitter:image输出的是相对资源路径,Discord、LinkedIn、Mastodon、Slack 等外部爬虫无法解析。
  • 修复:相对值现在统一加site.url+site.baseurl前缀,与og:url的既有构建方式保持一致;已为绝对值的 URL 保持原样,避免 CDN URL 被二次加前缀。对应 issue #3666。

3.4 CV 条目的日期徽章缺失(al_folio_cv1.0.2)

  • 主 bug:五个 CV 分区中有三个只读取start_date/startDate,因此只携带单个date:字段的 RenderCV 条目什么都不显示。而al_cv_sort_by_date已经按该键排序——条目被静默挪到时间序位置,却没有任何显示来解释原因。本次修复同时为 Projects 增加了完整的日期渲染。对应 issue #3339。
  • 次生 bug{% capture %}会保留周围空白,导致 awards 和 publications 分区的"空内容"判断永远不成立,无日期条目反而渲染出一个空的徽章列

3.5 CV 条目按源码顺序渲染(al_folio_cv1.0.1)

  • 现象:volunteering 总是被追加在工作历史之后,而不是按时间线交错排列。
  • 修复:新增al_cv_sort_by_date过滤器,统一理解 RenderCV 与 JSONResume 两种键名、部分日期(20202020-06)、YAML 日期对象、文本形式的present结束日期以及无日期条目。
  • 附带修复:悬空的日期分隔符——无结束日期的条目渲染Present;完全无日期的条目不渲染徽章;无位置的条目不再渲染孤零零的地图图钉行。

3.6 外部文章以空标题发布(al_ext_posts1.0.3)

  • 现象:当抓取降级(页面不可达、无<title>、RSS 条目为空)时,文章在博客索引中渲染成一行空白但可点击的条目,并产生一连串Empty slug generated警告。
  • 修复:从 URL 最后一个有意义的路径段推导可读标题,并记录一条带 URL 的警告。slug 与 URL 保持不变。

3.7 无样式的 popover 与 tooltip(al_folio_core1.0.11,由 #3636 锁定)

禁用 bootstrap-compat 时使用的原生回退方案会在tooltips-setup.js中创建.af-popover/.af-tooltip元素,但此前它们完全没有定位与视觉样式,表现为无定位的浮动文本。

3.8 统计卡片失败时的破损 alt 文本(al_folio_core1.0.11,由 #3636 锁定)

所有仓库统计卡片图片现在都带onerror处理器:当外部统计卡片或 trophy 服务不可用时,卡片会优雅隐藏,而不是显示破损的 alt 文本。


四、✨ 改进:从 Cloudflare Analytics 到自托管 Star History 图

4.1 Cloudflare Web Analytics 支持(al_analytics1.0.2)

免费、无 Cookie、无抽样的站点分析。在_config.ymlanalytics.cloudflare填入 beacon token 即可启用。对应 issue #3351。当前 _config.yml 已包含该配置项(cloudflare: # your Cloudflare Web Analytics beacon token (32 hex characters))。

4.2 Simple Analytics 支持(al_analytics1.0.1)

此前已随 1.0.0 发布但无人知晓,v1.1 起正式文档化。与其他所有 provider 不同,Simple Analytics没有 site ID 可配置——它按域名识别站点——因此仅由enable_simple_analytics一个开关控制。当前 _config.yml 中的注释("Simple Analytics identifies a site by its domain, so it has no ID to set above")正是这一设计的证据。

4.3 更快的搜索数据生成(al_search1.0.3)

原本用于查找首页标题的全量site.pages扫描被替换为单一过滤器链,并配有回归测试覆盖。在拥有大量页面的站点上,这能明显缩短构建时间。

4.4 自托管 Star History 图表(#3684、#3685)

  • 背景:README 中的图表此前来自 star-history.com,该服务曾不可用。
  • 修复:改为仓库内生成——由 bin/generate_star_history.py 输出,仅依赖 Python 标准库、零第三方依赖,按浅色/深色双主题输出,并在每次 push 到main时自动刷新,外加每周刷新一次。
  • 实现细节:脚本通过 GitHub 公开的 stargazer 时间戳 API 采样(默认 28 个样本点,超过 400 页分页上限时对尾部做插值并在图中标注),输出assets/img/star-history-light.svgassets/img/star-history-dark.svg两个静态文件,由 README 中的<picture>+prefers-color-scheme在明暗模式下切换。运行方式:python3 bin/generate_star_history.py [--repo owner/name] [--out-dir DIR]GITHUB_TOKEN可选但强烈建议(未认证 API 每小时仅 60 次请求,对数千星以上的仓库不够用)。

五、📚 文档与 🔧 基础设施:面向 Agent 与自动化发布

5.1 文档:一次面向 Agent 友好性的全面修订(#3681)

  • AGENTS.md 成为编码 Agent 的权威入口——涵盖变更路由、gem 所有权"停止标志"、三种无报错静默失败模式,以及经过验证的命令集。
  • docs/ARCHITECTURE.md 解释启动器与 gem 如何配合;docs/BOUNDARIES.md 是权威的"功能区域 → gem 所有权"对照表。
  • SHOWCASE(案例展示)从 README 移入 docs/SHOWCASE.md。
  • 全文修正事实性错误,并确立"每条事实只在一个地方存在、其余用链接引用"的文档纪律。

5.2 发布自动化

此前没有任何 gem 是从 CI 发布的——这正是多个修复在main上积压、却从未送达用户的原因。v1.1 起全部 16 个插件仓库都接入了 tag 驱动的release.yml,它具备四重保障:

  1. 校验 tag 与 gemspec 版本一致;
  2. 拒绝覆盖已发布的版本;
  3. 对构建产物运行完整测试套件;
  4. 拒绝从 fork 触发。

5.3 依赖升级与死配置清理

  • 依赖升级:nokogiri1.19.3 → 1.19.4(#3653)、concurrent-ruby1.3.6 → 1.3.7(#3654)、loofah2.25.1 → 2.25.2(#3676)、json2.19.7 → 2.19.9(#3678)。
  • 删除死配置:third_party_libraries.polyfill配置项(al_math1.0.2 之后已无代码读取)。

六、⬆️ 升级指南:三步完成 v1.0 → v1.1

由于版本 pin 是精确的,升级是两步配置修改 + 一步验证的流程,只跑 Bundler 不会改变任何东西。

步骤 1:更新Gemfile中的版本 pin

group :al_folio_plugins中各插件的版本改为上文表格中 v1.1 一列。如果你没有定制过该文件,最省事的方式是直接复制本发布版对应的group :al_folio_plugins代码块。以当前仓库 Gemfile 为参考,该块的形式为:

group :al_folio_plugins do gem 'al_folio_core', '= 1.0.12' gem 'al_folio_cv', '= 1.0.2' gem 'al_folio_distill', '= 1.0.3' gem 'al_analytics', '= 1.0.2' gem 'al_ext_posts', '= 1.0.3' gem 'al_img_tools', '= 1.0.3' gem 'al_search', '= 1.0.3' gem 'al_math', '= 1.0.2' # ... 其余插件保持或按需更新 end

步骤 2:更新_config.yml

al_folio: distill: allow_remote_loader: false # 原来是 true;保持 true 等于退出 Distill 加固

同时可以删除已无用的third_party_libraries.polyfill条目——al_math1.0.2 起已无任何代码读取它。

步骤 3:安装并验证

bundle install bundle exec al-folio upgrade audit
  • audit 的含义:只要allow_remote_loader仍为true,audit 就会报告一个blocking(阻塞级)发现项,这是步骤 2 的最后一道保险。al_folio_upgradegem(由 test/integration_upgrade_cli.sh 集成测试覆盖)负责这套 CLI 与审计报告(al-folio-upgrade-report.md)的生成。
  • 验证修复是否真正落地:不要靠猜,直接检查解析后的实际版本:
bundle list | grep -E 'al_img_tools|al_math|al_folio_distill'

你需要看到al_img_tools 1.0.3或更新——它就是携带 CVSS 9.4 修复的那个版本

兼容性结论

除上述安全与配置变更外,v1.1 中的一切向后兼容:不需要任何模板、布局或内容改动。这也与 docs/ARCHITECTURE.md 中"_config.yml必须保留al_folio契约键,由构建期告警与 upgrade audit 双重强制"的机制相互印证——升级审计正是防止配置漂移的自动化防线。


七、小结:v1.1 对存量站点的意义

对任何运行 v1.0 的 al-folio 站点,v1.1 是一次必须执行的升级:它不仅修复了 CVSS 9.4 级别的原型污染漏洞、消除了 polyfill.io 供应链攻击面与 Distill 远程加载的无 SRI 执行风险,还修复了仓库卡片空白、移动端子菜单越界、CV 日期徽章缺失等直接影响日常使用的缺陷。与此同时,v1.1 确立了两条对后续版本影响深远的工程惯例:发布自动化(CI 校验、防覆盖、防 fork 触发)与精确 pin + 升级审计bundle update不够,必须改 pin、跑 audit、查bundle list)。理解 v1.1 的升级机制,也就掌握了后续 v1.2 及更高版本升级的通用方法。

【免费下载链接】al-folioA beautiful, simple, clean, and responsive Jekyll theme for academics项目地址: https://gitcode.com/GitHub_Trending/al/al-folio

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询