兩個月前,我在《》里立了一個 flag,接盤上游跑路留下的爛攤子,跟 CVE 修 Bug。那篇文章上了幾個小時的 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 把開源倉庫改成 維護模式[3]。README 里寫著 “安全修復會逐例評估”。 到 2026 年 2 月,倉庫直接歸檔,首頁變成了 “當前倉庫已經不再維護”。但同一個倉庫的 SECURITY.md[4] 還留著:“我們總會為最新版本提供安全更新”。
而最近一個月,MinIO 又暴漏出四個高危漏洞,兩個中危,覆蓋最后的開源版本。而在官方公告里寫道:他們的商業版本 AIStor 修復了這些問題,給開源用戶的建議是:“升級到 AIStor”。
![]()
順便一提,MinIO AIStor 入門起步價約 10 萬美元/年,400 TiB,單價基本跟 AWS S3 差不多 —— 離了大譜,畢竟這是純軟件。一種很精致的玩法。倉庫歸檔了,道義責任撇清了;但 CVE 通告照發,既能刷一波 “我們很負責任” 的存在感,又恰好能把用戶趕進商業版的羊圈。
只是還得有人得把這坑填上。
這次修了什么
這篇文章我不想寫成漏洞分析報告。具體每一條的 CVSS 分數、攻擊鏈、PoC 代碼,我在 發布注記[5] 里都一一列了,感興趣的朋友可以去看。這里只說一句話版本:
?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 Coding Agent 來維護這個項目,事實上我也是這么做的。這一輪修復里,我扮演了一個 Blind Manager 的角色。
簡單解釋一下我的工作范式。具體到每一條漏洞,流程大致是:
1.Codex 先打鐵:根據 CVE 描述和相關代碼路徑,產出第一版補丁。2.Claude Code 做 review:站在對抗視角挑毛病。3.回到 Codex:我要求它,如果你同意 Claude Code 的意見,那就返工;如果不同意,那就反駁,把理由寫清楚。4.把所有思路攤開,再交給 Claude Code 做一輪 review。必要時來回再跑幾輪,直到兩邊收斂。5.進行測試:依然是類似的對抗操作,由 Codex 設計測試用例,Claude 補充。然后由 Codex 去實際執行并產出結果,再由 Claude Code review。6.我來定奪:看 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 那條 fix。表面上,它是一個 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 不是情懷,也不是 cosplay。它存在,首先是因為這是我自己要用的東西。
MinIO 是 Pigsty 的生產依賴。我需要可用的二進制、完整的控制臺、持續可得的包,以及真正有人處理的 CVE 補丁。也正因為我自己在用,所以這條線沒有太多空話空間:它不是拿來講故事的,而是拿來頂生產環境的。
這也決定了我的策略很保守。不會去追求 “新特性很酷”,也不會把倉庫弄成另一個方向的實驗場。我的目標一直都很明確:保持兼容,守住供應鏈,在該修的時候把問題修掉。
到現在,這個分支在 GitHub 已經有了 1300 star,在 Docker Hub 也累計了 五萬+ 下載。數字本身不算什么驚人的成就,但它至少說明了一件事:需要這條線的人,并不只有我自己。
![]()
對已經在用 MinIO 開源版的人來說,遷移到這個分支的成本其實很低:
?Docker 鏡像:把 minio/minio 換成 pgsty/minio,一行的事。?RPM / DEB:GitHub Release[6] 里都有,或者用 pig 一鍵裝。?源代碼倉庫:pgsty/minio[7]?文檔鏡像站:silo.pigsty.cc[8]?英文文檔:silo.pigsty.io[9]
你不需要換掉整個系統,也不需要重新學習一套對象存儲;多數情況下,只是把一個失去維護的上游,替換成一個還會繼續交付補丁的分支。
如果你需要完整的生產級部署方案,Pigsty 里也提供了開源免費、開箱即用的 MinIO 生產級高可用部署支持。
![]()
承諾是什么
對老馮來說,這就是一件很普通的事情,用的東西壞了,自己修一下。僅此而已。
只是到了 2026 年,“自己修一下” 這件事的門檻,被 AI Coding Agent 重新定義了。一個人,加兩個 agent,加一點點判斷力,足以把一個六萬 star 的中型基礎設施頂起來。這不是我厲害,這是時代變了。
以前我們談論開源的韌性,談的是 “社區”,幾十上百個志愿者眾籌時間。現在這套劇本還在,但底下多了一層保險:哪怕社區散了,只要有一個人還愿意按下 fork 按鈕,項目就能續命。
承諾是什么?承諾是 “下一個 CVE 出來的時候,我還在”。
![]()
下一個 CVE 出來的時候,老馮還在。
就這樣。
![]()
References
[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
數據庫老司機
點一個關注 ??,精彩不迷路
對 PostgreSQL, Pigsty,下云,AI 感興趣的朋友
歡迎加入 PGSQL x Pigsty 交流群 QQ 619377403
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.