LiteLLM 1.107.0 惡意套件事件:檢查感染痕跡與設定 3 日延遲安裝
LiteLLM 1.107.0 was malware. A 5-minute check for AI developers, and the one-line setting that would have skipped it
LiteLLM 1.107.0 於 2026 年 10 月 21 日被上傳至 PyPI 的惡意套件會竊取 AI 開發工具憑證並每小時執行遠端程式碼;PyPI 已移除該版本,1.106.2 安全。
文章把 LiteLLM 供應鏈事件整理成可操作的排查與防護步驟,並比較 uv、pip 延遲接受新版本的設定及其對緊急修補的取捨。
2026 年 10 月 21 日,有人向 PyPI 發布了一個惡意 litellm==1.107.0。這是該套件今年第二次遭入侵,與 3 月的事件無關。PyPI 已將其移除,而 1.106.2 是安全版本。
如果你使用 LLM 建置軟件,即使從未自行安裝 LiteLLM,你的電腦上也很有可能有它。不少 Agent 和代理伺服器都會透過它,以單一介面連接 Claude、GPT 等服務。這令這次事件特別棘手:惡意程式會按名稱搜尋 AI 編碼工具的憑證,包括 Claude、Cursor、Copilot、Gemini CLI 和 Codex CLI。
GMO Flatt Security 發布了我見過最詳盡的分析,但內容是日文。本文以英文概述該分析,並補充我在其他分析文章中都找不到的一項內容:如何讓 uv 和 pip 拒絕剛發布的版本。
https://blog.flatt.tech/entry/litellm_2nd_compromise
事件經過
以下時間線根據 Flatt Security 的分析及 PyPI 的發布資料整理。所有時間均為 UTC。
| 時間 | 事件 |
|---|---|
| 10-13 06:43 | 攻擊者建立 GitHub 帳戶 |
| 10-13 06:46 | 資料外傳網域 litellm[.]dev 的 TLS 憑證簽發
|
| 10-21 10:44 | 正式版 1.106.2 發布 |
| 10-21 11:39 | 惡意版本 1.107.0 約一小時後發布 |
| 10-21 | PyPI 移除 1.107.0 |
GitHub 上的 v1.107.0 標籤未受污染。惡意檔案只存在於上載至 PyPI 的 wheel 檔案中,因此閲讀原始碼也無法幫你避過這次攻擊。
它也不會等你匯入任何內容。wheel 會將一個 .pth 檔案和一個 sitecustomize.py 放進 site-packages,而 Python 每次啟動時都會載入兩者。該環境中的任何 Python 程序都會令它啟動。除了竊取資料,它還會啟動一個守護程序,每小時下載並執行遠端程式碼;伺服器位址則從 GitHub 上的一個檔案讀取。
發布時機也很巧妙。1.107.0rc1 和 rc2 幾日前已如常發布,因此接下來再發布最後一個 1.107.0 正合預期。如果你在 10 月 21 日執行 pip install -U litellm,你就是這次攻擊的目標。
被竊取的資料
Flatt Security 整理出 16 類資料。對 AI 開發者而言,AI 工具憑證顯然最令人擔心:Claude、Cursor、Copilot、Gemini CLI、Codex CLI、Windsurf、Aider、OpenCode 和 Hugging Face 權杖都在清單上。
環境變數則較容易被忽略。它會透過 /proc/*/environ 讀取自身及其他程序的環境變數,因此,如果你透過這種方式傳入 ANTHROPIC_API_KEY 或 OPENAI_API_KEY,就應假設它們已被竊取。它也會收集 .env 檔案和私鑰檔案;如果你有執行 LiteLLM 代理伺服器,它還會查詢代理伺服器的資料庫,取得其中儲存的服務供應商金鑰。SSH 金鑰、雲端憑證、瀏覽器密碼和 Shell 歷史紀錄也在竊取範圍內。
補充説明 Claude Code。根據官方文件,它在 macOS 上透過 Keychain 儲存憑證,在 Linux 和 Windows 上則儲存在 ~/.claude/.credentials.json。如果 Keychain 無法寫入,macOS 會改用該檔案;透過 SSH 連線時便會出現這種情況。如果你在 CI 或 Linux 伺服器上執行 Claude Code,應視該檔案已外洩。
5 分鐘檢查
我在自己的 Mac 上執行了所有檢查。結果一無所獲,但單靠 pip show 我無法得知這點,因為它只會檢查目前啟用的環境。
搜尋 dist-info 資料夾效果更好。版本號就在資料夾名稱中,而且也能找到藏在 uv tool 和 pipx 環境中的副本。
find ~ -maxdepth 8 -type d -iname 'litellm-*.dist-info' 2>/dev/null
如果看到 litellm-1.107.0.dist-info,該環境便已受感染。
接下來檢查鎖定檔。如果鎖定使用 1.107.0,任何人從內部鏡像站或快取重建該環境時都會受感染。
grep -rIl -i 'litellm' --include='requirements*.txt' --include='pyproject.toml' \
--include='uv.lock' --include='poetry.lock' ~/code 2>/dev/null
然後搜尋惡意程式留下的檔案。
ls -la /tmp/.pc_once_72129118c59f5636c0bb /tmp/remote_code_loader.lock 2>&1
ps aux | grep -E 'cook|remote_code_loader' | grep -v grep
第一個檔案代表你的資料已經傳送出去。鎖定檔案或相符的程序代表後門正在運作。請注意,macOS 重新啟動時會清除 /tmp,所以單憑找不到它們並不能證明太多。請連同 find 的結果一併判讀。
如果你受到影響,請按照 Flatt Security 的移除步驟處理,然後把所有憑證都視同已遭盜取般輪換。我認為 AI 開發者最容易忘記輪換的,是模型供應商的 API 金鑰(Anthropic Console、OpenAI、Google AI Studio)、Claude Code 的登入憑證(/logout,然後 /login;Cursor 或 Codex 也一樣),以及 LiteLLM 代理伺服器中儲存的每一個金鑰。接下來就是常見項目:.env 的內容、GitHub 和套件登錄檔權杖、SSH 金鑰和雲端憑證。如果你發現任何可疑項目,也值得查看各供應商的用量頁面,檢查 10 月 21 日以來有沒有不認識的用量。
不要安裝發布時間未滿 3 日的套件
有問題的版本上架不到一天。如果你的安裝程式會忽略發布時間只有幾小時的版本,你根本不會察覺就能避開它。Flatt Security 使用設有 3 日隔離期的套件登錄檔代理伺服器,其用戶沒有受到影響。不過,你不需要代理伺服器也能達到相同效果。現在 uv 和 pip 都能做到。
在 uv 中,exclude-newer 接受 24 hours、1 week 或 3 days 這類時間長度,也接受 P3D 這類 ISO 8601 時間長度,並會與每個檔案的上載時間比較。
# pyproject.toml
[tool.uv]
exclude-newer = "3 days"
如要全域設定 ~/.config/uv/uv.toml,請省略 [tool.uv] 這一行。
在 pip 中,選項是 --uploaded-prior-to,並以 P3D 格式指定日數。這個選項只適用於會回報上載時間的套件索引,而 PyPI 會回報。如果你的 pip 不認得這個選項,請升級 pip。
pip install --uploaded-prior-to P3D litellm
# or make it the default
export PIP_UPLOADED_PRIOR_TO=P3D
缺點是緊急修正也會被延後,而且你不能把當日發布的安全修補程式擱置三天。uv 透過 exclude-newer-package 處理這個問題,讓你可以豁免單一套件。
[tool.uv]
exclude-newer = "3 days"
exclude-newer-package = { cryptography = false }
使用 pip 時,只需在該次安裝取消設定這個變數。我喜歡這種做法,因為跳過延遲會變成一個刻意的操作,並會記錄在 shell 歷史記錄或提交紀錄中,而不是預設發生。
如果你使用 Node.js,pnpm 也有一項可實現相同功能的設定,名為 minimumReleaseAge(https://pnpm.io/settings)。
總結
litellm==1.107.0 是惡意軟件,而應使用的版本是 1.106.2。使用 find 搜尋已安裝的副本,而不要只相信 pip show;檢查鎖定檔案,如找到它,請連同其他所有憑證一併輪換各供應商的 API 金鑰。日後若在 uv 或 pip 設定 3 日延遲,本可阻止這個版本安裝到你的電腦上。
如果你在 Claude Managed Agents 上執行 Claude agents,還有一點要留意。類型為 environment_variable 的 Vault 憑證只會以佔位符形式存在於沙盒內,並會在離開沙盒時換成真正的密鑰。因此,若遭污染的相依套件傾印環境變數,取得的只會是佔位符。文件在此:https://platform.claude.com/docs/en/managed-agents/vaults
Claude API 有更新時,我會撰寫相關文章。我的 Claude 5 遷移指南英文版已在 Gumroad 上架:https://persimmoq.gumroad.com/l/claude-5-migration-guide
來源:DEV Community · dev.to