LiteLLM 1.107.0 惡意版本排查與套件延遲安裝設定
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,惡意 wheel 會在每次 Python 啟動時執行並竊取 AI 工具憑證等資料;安全版本為 1.106.2。
這篇文章將 LiteLLM 事件轉化為可執行的排查清單,並示範用 uv 或 pip 延後安裝新版本及為緊急修補設例外。
2026 年 10 月 21 日,一個惡意的 litellm==1.107.0 被發布到 PyPI。這是該套件今年第二次遭入侵,與 3 月的一次事件無關。PyPI 已將其移除。安全版本為 1.106.2。
LiteLLM 是許多 Agent 和代理程式用來透過單一介面呼叫 Claude、GPT 及其他模型的程式庫。它往往會以相依套件的形式出現,而你並非刻意安裝它。這個載荷會明確針對各種 AI 編碼工具的憑證下手,包括 Claude、Cursor、Copilot、Gemini CLI、Codex CLI 等。
目前最佳的技術分析是 GMO Flatt Security 撰寫的文章(日文)。本文為英語讀者整理其內容,並補充我未能在其他地方找到的部分:如何讓安裝程式拒絕全新發布的版本。
https://blog.flatt.tech/entry/litellm_2nd_compromise
發生了甚麼事
時間均為 UTC,根據 Flatt Security 的時間線及 PyPI 的發布資料整理。
| 時間 | 事件 |
|---|---|
| 10-13 06:43 | 攻擊者的 GitHub 帳戶建立 |
| 10-13 06:46 |
TLS 憑證為資料外洩網域 litellm[.]dev 簽發
|
| 10-21 10:44 | 合法版本 1.106.2 發布 |
| 10-21 11:39 | 惡意版本 1.107.0 發布,約一小時後 |
| 10-21 | PyPI 移除 1.107.0 |
有三個細節值得留意。
- GitHub 上的標籤是乾淨的。惡意檔案只存在於 PyPI 上的 wheel 中。查看原始碼並不能發現它。
-
它會在每次 Python 啟動時執行,不只是在匯入時執行。wheel 會將
.pth檔案和sitecustomize.py放入site-packages。Python 啟動時會自動載入兩者,因此該環境中的任何 Python 程序都會觸發它,即使該程序從未匯入litellm。 - 它會留下後門。一個常駐程式每小時都會擷取並執行遠端程式碼,而 C2 網域則從 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 tokens
-
環境變數,包括透過
/proc/*/environ取得其他程序的環境變數。如果你將ANTHROPIC_API_KEY或OPENAI_API_KEY作為環境變數傳入,就應假設它們已外洩 -
.env檔案及私密金鑰檔案 - LiteLLM 自身的資料庫,如果你有執行代理伺服器:它會查詢憑證資料表,取得你的供應商金鑰
- SSH 金鑰、AWS / GCP / Azure 憑證、瀏覽器儲存的密碼、Shell 歷程記錄
至於 Claude Code,根據官方文件,macOS 上的憑證儲存在macOS Keychain,Linux 和 Windows 上則儲存在~/.claude/.credentials.json。如果無法寫入 Keychain,例如透過 SSH 使用時,macOS 也會改用該檔案。如果你在 CI 或 Linux 電腦上執行 Claude Code,請視該檔案已外洩。
5 分鐘檢查
我在自己的 Mac 上執行了以下檢查。沒有任何項目符合,但單靠 pip show 並不能讓我得知這一點。
1. 找出所有已安裝的副本。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 表示該環境已受感染。
2. 檢查鎖定檔。如果 1.107.0 的版本已固定,任何人從內部鏡像或快取重建環境時,都可能再次受到感染。
grep -rIl -i 'litellm' --include='requirements*.txt' --include='pyproject.toml' \
--include='uv.lock' --include='poetry.lock' ~/code 2>/dev/null
3. 尋找標記。
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 會在重新啟動時清除,因此單憑找不到標記並不能證明系統安全。請配合第 1 步一併檢查。
4. 如果你受到影響,請按照 Flatt Security 的移除步驟操作,然後假設所有資料均已遭盜取,全面輪換憑證。以下是大家容易忽略的 AI 相關項目:
- 在 Anthropic Console、OpenAI、Google AI Studio 及其他供應商的平台撤銷並重新發出 API 金鑰
- Claude Code:
/logout,然後/login。Cursor、Codex 及其他工具也要照做 - LiteLLM 代理伺服器中儲存的每個供應商金鑰
- 你所有
.env檔案中的所有內容 - GitHub 權杖、PyPI/npm 權杖、SSH 金鑰、雲端憑證
另外,請查看各供應商的用量頁面,檢查 10 月 21 日起有沒有你不認識的流量。
不要安裝發布未滿 3 天的套件
該惡意版本只上架了不到一天。拒絕安裝發布僅數小時的版本,就能完全避開它。Flatt Security 自家的套件庫代理伺服器設有 3 天隔離期,其用戶因此未受影響。你也可以使用 uv 和 pip 已內置的功能達到同樣效果。
uv:exclude-newer 接受例如 24 hours、1 week 或 3 days 這類時長,也接受 ISO 8601 時長,例如 P3D。系統會將其與各檔案的上載時間比較。
# pyproject.toml
[tool.uv]
exclude-newer = "3 days"
在全域 ~/.config/uv/uv.toml 中,刪除 [tool.uv] 那一行,並保留 exclude-newer = "3 days"。
pip:--uploaded-prior-to 接受以 P3D 格式表示的日數。這只適用於會提供上載時間的套件索引,而 PyPI 就有提供。
pip install --uploaded-prior-to P3D litellm
# or make it the default
export PIP_UPLOADED_PRIOR_TO=P3D
如果你的 pip 不認得這個選項,請升級 pip。
要注意的是,緊急修正不能等。如果某個程式庫在同一天推出安全性修正,你就不能等 3 天。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。GitHub 上的原始碼沒有問題;只有 PyPI 的 wheel 套件遭植入惡意程式。- 它會在每次 Python 啟動時執行,並以 AI 工具憑證、環境變數、
.env檔案及 LiteLLM 代理伺服器資料庫為目標。 - 使用
find檢查已安裝的版本,不要只用pip show。也要檢查鎖定檔案和標記檔案。 - 如果你受到影響,請輪換所有金鑰,包括模型供應商的 API 金鑰。
- 在 uv 設定
exclude-newer = "3 days",或在 pip 設定PIP_UPLOADED_PRIOR_TO=P3D,並明確豁免緊急修正。
如果你在 Claude Managed Agents 上執行 Claude agents,類型為 environment_variable 的保管庫憑證在沙盒中只會以不透明佔位符的形式存在,並會在資料流出時替換成真正的密鑰。因此,即使遭污染的相依套件傾印環境變數,取得的也只會是佔位符,而非金鑰:https://platform.claude.com/docs/en/managed-agents/vaults
我會在 Claude API 更新推出時撰寫相關文章。我在 Gumroad 上提供 Claude 5 遷移指南的英文版:https://persimmoq.gumroad.com/l/claude-5-migration-guide
來源:DEV Community · dev.to