MinIO 开源续命成功:3 天修复 4 个高危 CVE,AI 协作维护实战记录
距离立下那个 flag 已经过去两个月。当时我在《MinIO 已死,MinIO 复生》中宣布接盘上游跑路后留下的烂摊子,专职负责 CVE 漏洞修复工作。那篇文章曾一度登上 Hacker News 首页头条数小时,收获了不少鼓励,也招来不少质疑:单凭个人力量,真的能维护好这种规模的基础设施项目吗?
这个问题确实值得探讨。因为真正的考验从不是点击 fork 按钮那一刻,也不是修改 README 文档的时候,而是当安全漏洞真的找上门来之时。现在,我可以交出答卷了。
4 月 15 日至 17 日,短短三天内,pgsty/minio 发布了 RELEASE.2026-04-17 版本,连续修复并关闭了 4 条 CVE 及数条同期披露的安全漏洞,涵盖 OIDC JWT 算法混淆(CVSS 9.8)、LDAP 登录用户名枚举与暴力破解、复制头元数据注入导致对象不可读、S3 Select 超大记录打穿内存,以及两条 unsigned-trailer 写入路径上的签名绕过。
A promise made, a promise kept.
上游究竟发生了什么
2025 年 12 月,MinIO 将开源仓库切换至维护模式。README 文档中声称 “安全修复会逐例评估”。到了 2026 年 2 月,仓库直接被归档,首页显示 “当前仓库已经不再维护”。但同一仓库的 SECURITY.md 文件仍保留着:“我们总会为最新版本提供安全更新” 的承诺。
就在最近一个月,MinIO 接连爆出四个高危漏洞和两个中危漏洞,波及最后的开源版本。官方公告中明确表示:商业版本 AIStor 已修复这些问题,给开源用户的唯一建议是"升级到 AIStor"。

顺便提醒,MinIO AIStor 的入门起步价约为每年 10 万美元,包含 400 TiB 容量,单价基本与 AWS S3 持平——这实在离谱,毕竟这仅仅是纯软件。这是一种精巧的商业策略:仓库归档,道义责任撇清;但 CVE 通告照发,既能刷一波"我们很负责任"的存在感,又恰好能将用户驱赶到商业版的羊圈中。
只是,总需要有人来填补这个坑。
本次修复的核心内容
本文无意写成漏洞分析报告。每条漏洞的 CVSS 评分、攻击链、PoC 代码,我都已在发布注记中详细列出,感兴趣的朋友可以前往查阅。这里只做一句话总结:
•CVE-2026-33322(OIDC JWT 算法混淆,CVSS 9.8):在特定 IdP 配置下可伪造任意身份,包括 consoleAdmin。攻击者只要掌握 OIDC ClientSecret,从数学层面就能签发一张"我是管理员"的通行证,MinIO 会乖乖验证通过。影响范围从 2022 年 11 月持续至今年 3 月,长达三年半。
•CVE-2026-33419(LDAP STS 登录枚举与暴力破解):攻击者可先通过登录接口枚举真实用户名,随后在无速率限制的情况下爆破密码,最终直接获取 STS 凭证。整个链条从头到尾没有任何防护机制。
•CVE-2026-34204(复制头元数据注入):在普通 PUT / COPY 请求中夹带 X-Minio-Replication-* 头,就能将对象写入永久不可读状态,数据虽在,但再也无法读取。
•CVE-2026-39414(S3 Select 内存耗尽):一条恶意请求即可将 MinIO 进程吃到 OOM。
•GHSA-hv4r-mvr4-25vw / GHSA-9c4q-hq6p-c237:unsigned-trailer 路径上的两条签名校验绕过,匿名或伪造签名的请求可在特定路径下成功写入对象。

再加上 go-jose、go.opentelemetry.io 和 Go 1.26.2 自身吸收的一连串标准库与依赖 CVE,此版本累计聚合了近二十条安全条目。
有些能伪造身份获取高权限访问,有些能将登录接口用于枚举和爆破,有些能将对象写入永久不可读状态,有些能用单条请求将服务吃到 OOM,还有些能在缺失签名校验时直接写入对象。这绝非小修小补,而是实打实的维护责任。
修复工作如何完成
在此前文章中,我已明确表示会用 AI 编码助手来维护该项目,事实上我也是这么做的。这一轮修复中,我扮演的是Blind Manager角色。
具体解释一下我的工作范式。针对每条漏洞,流程大致如下:
- Codex 先行攻坚:根据 CVE 描述和相关代码路径,产出第一版补丁。
- Claude Code 负责审查:站在对抗视角挑刺找茬。
- 返回 Codex:我要求它,若认同 Claude Code 的意见则返工修改;若不认同则反驳,并将理由阐述清楚。
- 将所有思路摊开,再交由 Claude Code 进行一轮审查。必要时反复多轮,直至双方达成共识。
- 开展测试:依然采用类似的对抗操作,由 Codex 设计测试用例,Claude 负责补充。随后由 Codex 实际执行并产出结果,再由 Claude Code 审查。
- 我来做最终决策:查看 diff、运行测试、做最后验收。
这个过程中,我自己未写一行代码。我的工作在于定义问题、划定边界、挑选方案、查看 diff、运行验收、拍板定案。
在公开提交页上,你能直接看到 Vonng、Codex、Claude Code 三个名字同时出现在几条关键安全提交的 Co-authored-by 字段中。这不是作秀,这就是 2026 年一个人维护中型基础设施项目的真实写照。

这种协作模式具备几个实际优势。
**第一,两个 agent 对抗能过滤掉大部分"听起来都对、实际上不对"的方案。**单个 agent 修复安全漏洞时常表现出"幻觉级自信",写出一份解释流畅、看似完美的补丁,却漏掉某个边界条件。让另一个 agent 从敌对视角审视它,这种方案很难通过第一轮审查。
**第二,逼迫显式权衡。**当两家实现路径发生碰撞时,必须回答"为何你选 A 而我选 B"。这个对话本身就是将隐性假设显性化,而显性化的假设,正是我作为 Blind Manager 能够拍板决策的基础。
**第三,真正的维护是"补丁打补丁",而非一把梭。**以 LDAP STS 漏洞为例,首版修复推出后,很快发现成功请求不应消耗限流额度、默认不应信任 X-Forwarded-For、限流账户需按"源 IP + 归一化用户名"双维度计算。随后连续补充三次提交才彻底收敛。若缺少 agent 的火力支持,单靠一个 maintainer 一边读代码一边迭代,所需成本完全不同。

有些事情仍需人工决策
也正因为这种模式运转良好,maintainer 唯一的不可替代性,恰恰体现在那些 AI 无法给出最终答案的领域。
最典型的就是 OIDC 漏洞的修复。表面上是 JWT 算法混淆漏洞,实质上却是兼容性与安全性之间的取舍。
简单解释:JWT 签名算法分为非对称(RS256、ES256 等,签名用私钥、验签用公钥)和对称(HS256 等,签名和验签用同一密钥)两类。OIDC 的标准做法是 IdP 用私钥签 token,MinIO 通过公开的 JWKS 获取公钥来验签。公钥是公开的,攻击者无法获取私钥,因而无法伪造。
而 HS256 这类对称算法的问题在于:签名与验签使用同一密钥。该密钥即 MinIO 自身存储的 ClientSecret。于是攻击者一旦掌握这个"共享秘密",便既能当裁判又能当运动员。用自己持有的密钥签发 token,MinIO 用存储的同一密钥验证,自然通过。
这在教科书上是 JWT 的经典反模式,但历史代码正是如此演进。修复路径有几条可选:
•继续容忍这条历史路径,仅在特定条件下收窄:保留向后兼容,但安全边界依然模糊。 •严格采用 JWKS-only,拒绝 HS256 等对称签名 token:一刀切,安全边界清晰,但少数配置模糊的用户会遭遇配置失效。
两个 agent 可以为我列出每个方案的 trade-off,可以写好任一方案对应的补丁,但它们不会替我决策。最终我选择了后者,恢复严格的 JWKS-only 验证路径,明确拒绝不应接受的 HS256。
这个决定或许会让少数模糊配置失效,但安全边界终于清晰。AI 可以提出三个方案,真正承担后果的仍是 maintainer。
这就是 Blind Manager 模式的上限与下限:机器负责穷尽方案,人负责选择方向。
并非情怀,而是刚需
我始终强调,这个 fork 不是出于情怀,也不是角色扮演。它存在的首要原因,是我自身确实需要使用。
MinIO 是 Pigsty 的生产依赖。我需要可用的二进制文件、完整的控制台、持续可获取的软件包,以及真正有人处理的 CVE 补丁。正因为我自己在用,这条线没有太多空谈空间:它不是用来讲故事的,而是用来支撑生产环境的。
这也决定了我的策略极为保守。不会追求"新特性很酷",也不会将仓库引向另一个实验方向。我的目标始终明确:保持兼容,守住供应链,在必须修复时把问题彻底解决。
截至目前,该分支在 GitHub 已获得 1300 star,在 Docker Hub 累计 五万+ 下载。数字本身不算惊人成就,但至少说明一件事:需要这条线的不只有我自己。

对于正在使用 MinIO 开源版的用户而言,迁移到这个分支的成本其实很低:
•Docker 镜像:将 minio/minio 替换为 pgsty/minio,一行命令即可。
•RPM / DEB:可在 GitHub Release 中获取,或用 pig 一键安装。
•源代码仓库:pgsty/minio
•文档镜像站:silo.pigsty.cc
•英文文档:silo.pigsty.io
无需更换整个系统,也无需重新学习对象存储;多数情况下,只是将失去维护的上游替换为一个仍在持续交付补丁的分支。
如果需要完整的生产级部署方案,Pigsty 也提供了开源免费、开箱即用的 MinIO 生产级高可用部署支持。

承诺的真正含义
对老冯而言,这不过是一件再平常不过的事——用的东西坏了,自己修一下而已。
只是到了 2026 年,“自己修一下"的门槛被 AI 编码助手重新定义。一个人,加上两个 agent,再加一点点判断力,足以撑起一个拥有六万 star 的中型基础设施项目。这不是我多厉害,而是时代变了。
从前我们谈论开源的韧性,谈的是"社区”——几十上百个志愿者共同投入时间。这套剧本仍在,但底层多了一层保险:即便社区散去,只要还有人愿意按下 fork 按钮,项目就能续命。
承诺是什么?承诺就是**“下一个 CVE 出现时,我还在”**。

下一个 CVE 出现时,老冯还在。
就这样。

参考资料
[1] MinIO 已死,MinIO 复生: https://vonng.com/db/minio-resurrect/
[2] RELEASE.2026-04-17: https://github.com/pgsty/minio/releases/tag/RELEASE.2026-04-17T00-00-00Z
[3] 维护模式: https://github.com/minio/minio/commit/27742d469462e1561c776f88ca7a1f26816d69e2
[4] SECURITY.md: https://github.com/minio/minio/security
[5] 发布注记: https://silo.pigsty.cc/reference/release-note
[6] GitHub Release: https://github.com/pgsty/minio/releases
[7] pgsty/minio: https://github.com/pgsty/minio
[8] silo.pigsty.cc: https://silo.pigsty.cc
[9] silo.pigsty.io: https://silo.pigsty.io