PyPI 收緊舊版套件補檔窗口:推出 14 日後要開新版本再發 wheel
Tech News

PyPI 收緊舊版套件補檔窗口:推出 14 日後要開新版本再發 wheel

圖片:via iThome — https://www.ithome.com.tw/news/177656
TechLab 編輯部(譯)·

外洩 token 冇得向舊版塞檔,maintainer 要預早砌齊 wheel

14 日後,舊 release 會鎖住

PyPI 已經開始拒絕向推出超過 14 日嘅套件版本加入新檔案。以往 maintainer 發佈一個版本後,仲可以慢慢補交其他 wheel,例如 Windows、macOS、不同 CPU 架構,或者新版 Python 專用 build。呢份彈性幾方便,不過亦代表一個大家用咗好耐、以為內容穩定嘅版本,其實一直留住入口畀新檔案加入。新限制生效後,過咗限期就要另開版本號再發。

鎖死版本號,原來未必鎖死下載內容

一個 Python release 通常有 source distribution 同多個 wheel,pip 會按操作系統、CPU 架構同 Python 版本揀啱用嗰份。假設攻擊者偷到發佈 token,佢可以向舊 release 加一個特定平台專用嘅惡意 wheel;原有 Linux wheel 可以完全正常,得 Windows 或新版 Python user 中招。咁樣同一個版本號會同時存在乾淨同有毒嘅檔案,調查、封鎖同清理都麻煩好多。更重要係,只寫死 package==1.2.3 仍有機會下載到後加嘅檔案,有齊檔案 hash 嘅 lock file 先會即時發現內容唔同咗。

呢道閘針對未出現過嘅招數

PyPI 官方講得好清楚,暫時冇證據顯示攻擊者真係用過「向舊 release 補惡意檔案」呢一招。2026 年 3 月 LiteLLM 同 Telnyx 出事時,攻擊者用咗由受污染嘅 Trivy 發佈流程洩漏出嚟嘅 API token,上載帶有惡意程式嘅新版本。嗰兩宗事故唔係直接污染舊 release。不過事件證明 CI/CD 入面嘅憑證一失守,攻擊者確實有能力控制 PyPI 發佈,亦令擱置咗一段時間嘅舊版鎖檔討論重新郁返。

補 wheel 嘅流程要提早執好

maintainer 而家最好喺發版前砌齊 build matrix,先測試各平台 wheel,再由同一輪 CI 發佈全部檔案。漏咗某個平台而又趕得切 14 日限期,仍然可以補交;過咗期限,或者幾個月後先想支援新版 Python,就要升一個新版本號,即使 source code 冇實質改動都一樣。版本紀錄可以直接寫明只更新 packaging 或新增 wheel,等依賴方知道升級原因,亦要檢查 bot 同內部政策會唔會錯誤當成一般功能更新。

PyPI 提到,佢哋檢查下載量最高 15,000 個專案為 Python 3.14 後補 wheel 嘅情況,只有 56 個專案喺原有版本推出超過 14 日後先補 cp314 wheel。呢個數字支持新規則對主流套件影響有限,不過佢只涵蓋 Python 3.14、指定 wheel 同頭 15,000 個專案,唔代表其他平台 wheel、source distribution 或較細專案完全冇用開遲補檔。維護冷門 native extension 嘅團隊,反而要特別檢查自己慣常隔幾耐先補齊 build。

14 日限制唔會救晒受控 CI

攻擊者就算冇得改舊版,只要仲揸住有效憑證,仍然可以發佈一個新版本。maintainer 所以仲要釘死 GitHub Actions 等 CI 依賴嘅 commit SHA、避開可由外部輸入觸發指令嘅 workflow,亦應用 PyPI Trusted Publishers 取代長期 API token。Trusted Publishers 用短期 OIDC 憑證,就算洩漏,有效時間亦短好多。用套件嗰邊就要保留 hash lock、審查依賴更新,有條件亦可以設 dependency cooldown,減低惡意新版一出街就自動入 production 嘅風險。

正式嘅「關閉」狀態仲未定案

而家 14 日拒絕補檔已經係 PyPI 實際限制,不過官方提醒,生態系統仲未有正式規格定義 release 幾時算「關閉」,亦冇標準 API 畀工具查詢。仍屬草案嘅 PEP 694 打算用 Upload 2.0 同 staged previews 補返呢部分:maintainer 可以先上載同測試成套檔案,再一次過公開,工具亦可以查發佈 session 狀態。喺規格同實作完成前,CI 應直接處理上載失敗,再按 14 日規則開新版本,唔好自行估算 release 狀態。


參考來源

本文根據原文及公開資料整理;資料有出入時,以原文及官方資料為準。

分享:WhatsAppThreadsTelegramFacebook