檢查日期 2026-09-09|耗時 87 分鐘|對應卡片 CM-1617
找到一個全新的問題:公司內部的套件倉庫走的是沒加密的連線,而且 26 個專案全部一樣——有心人可以在我們安裝套件時掉包,把惡意程式塞進出貨的產品裡。
另外,這一棒還回答了一個困擾很久的問題:一次檢查 40 個檔案,工具撐不撐得住?答案是撐得住。
問題單的「業務邏輯層」——建單、改單、查單、標籤、成員、附件的流程安排,以及誰能做什麼的判斷。共 40 個檔案。
這是刻意的一次壓力測試:之前的經驗是「一棒不要超過 30 個檔」,這次故意放到 40,看工具撐不撐得住。
| # | 嚴重度 | 這是什麼問題 | 出事會怎樣 | 要先有什麼才打得到 | 在哪裡 | 修正卡 |
|---|---|---|---|---|---|---|
| 1、2 | 🟡 中 | 連 GitHub 沒檢查對方身分 | — | — | — | 重複(已隨對應項修掉) |
| 3 | 🟡 中 ⚠️ 範圍外 |
舊設定檔的密碼留在版控歷史 | — | — | — | 重複;舊案殘留已清(CM-2048) |
| 4 | 🟡 中 | 🆕 **公司內部的套件倉庫走沒加密的連線(HTTP),而且被設成「主要來源」——所有套件都從這裡下載 | 能在公司內網做手腳的人,可以在有人執行 poetry update 時掉包任何一個套件**。Python 安裝套件時會執行安裝腳本,等於在開發機和打包機上執行攻擊者的程式碼——而打包機產出的正是要交給客戶的安裝檔 |
① 攻擊者要在公司內網、且位於開發機與套件倉庫之間 ② 要有人執行 poetry update(或沒有版本鎖定檔的全新安裝) |
pyproject.toml 第 77 行 |
✅ 已修(版本鎖定檔入版控,連線維持 http 為決策者裁定;原卡 CM-1634 作廢) |
這棒的新問題:1 個。
白話:我們公司自己架了一個「套件倉庫」(叫 Nexus),所有專案要用到的套件都從那裡下載。但那個倉庫用的是沒加密的 HTTP 連線,而且被設定成「主要來源」——連公開的第三方套件也都繞道走它。
# jedi-issue/pyproject.toml 第 76-78 行
[[tool.poetry.source]]
name = "nexus"
url = "http://192.168.50.171:8082/repository/pypi-group/simple"
# ↑ http 沒有 s,代表沒有加密
priority = "primary"
# ↑ 主要來源,所有套件都走這條出事會怎樣:沒加密的連線,中途可以被改。有心人在公司內網做手腳,就能在有人執行 poetry update 的時候,把某個套件換成他的版本。Python 裝套件時會執行安裝腳本,所以那等於直接在開發機或打包機上執行他的程式碼。
最麻煩的是:打包機(188 那台)產出的就是要交給客戶的安裝檔。而且被換掉的套件雜湊值會寫進版本鎖定檔,之後每次安裝都照著用——包括打包進客戶的產品裡。
首腦另外查了報告沒查的範圍:
| 查什麼 | 結果 |
|---|---|
| 這個專案的版本鎖定檔 | 93 個套件來源全部是這個 http 網址 |
| jedi 套件庫裡有幾支這樣 | 25 支套件全部一樣 |
| 主專案呢 | 也是同一個(pyproject.toml 第 266 行) |
合計 26 個專案。
為什麼是「中」不是「高」:攻擊者必須人在公司內網、而且剛好位於開發機與倉庫之間的路徑上。另外,已經有版本鎖定檔、且雜湊驗證通過的安裝不受影響——除非鎖定檔本身已經被汙染。
怎麼修:這一條不是改程式碼能解決的,要基礎設施先動:
http:// 改成 https://poetry update 當成特權操作,只在可信任的網段執行這比找到的問題更重要。
背景:工具的驗證機制是「三個獨立檢查員對每條發現各投一票」。範圍太大時,這些檢查員會因為額度用盡而集體掛掉——之前 FR-077 那次就是這樣,105 個檢查員全部掛掉,21 張票一張都沒投出來,整輪報告是空的。
從那之後,規矩訂成「一棒不要超過 30 個檔」。
這次故意放到 40 個檔,結果:
| 檔數 | 投票結果 | 當時的條件 | |
|---|---|---|---|
| FR-077 那次 | 42 | ❌ 全滅(105 個檢查員全掛、21 票 0 投) | 連續跑,和其他棒搶額度 |
| 這一棒 | 40 | ✅ 15 票全投、零漏投、零中斷、一輪跑完 | 分開跑,獨佔額度 |
同樣是 40 個檔級別,一個全滅一個全過——差別不在檔數,在有沒有和別的工作搶額度。
所以規矩可以改成:「40 個檔可行,前提是一次只跑一棒。」
這一整個 arc 六棒一次都沒有撞到額度,對照 FR-079 那棒撞了兩次、跑了 14 小時、還踩到工具的併檔陷阱。這是決策者堅持「分開來跑」直接換到的結論。
檢查員 3 票否決了一條「成員名單可能外洩」的候選,理由有兩個:那段程式碼沒有任何入口到得了、以及插件裝配時缺少認證設定會直接拒絕掛載。
後者正是 I4 那棒首腦自己打開檔案查到的事。工具這次獨立確認,兩邊對上了。
全部 3 票全過,15 票全數投出、零漏投、零中斷,而且檢查員沒有降低任何一條的嚴重度。第 4 條首腦自己打開檔案核對過,還多查了影響範圍(26 個專案)。
快篩模式。40 個檔裡有 18 個是幾乎空白的檔案,實際有內容的約 22 個。
| 項目 | 數字 |
|---|---|
| 檢查範圍 | 40 個檔案(壓力測試) |
| 派出/回報的研究員 | 2 / 2 |
| 候選問題 → 去除重複 | 7 → 5 |
| 投票數 | 15(5 條 × 3 個檢查員) |
| 沒投到票的 | 0 |
| 投票中斷的 | 0 |
| 驗證輪次 | 1(一輪就跑完) |
| 耗時 | 87 分鐘 |