10 月 21 日晚上,Python 圈出了一件大事:AI 网关库 LiteLLM 在 PyPI 上发布的 1.107.0 版本被人动了手脚,里面夹带了一个凭据窃取程序和一个远程执行后门。只要这个版本被装进某个 Python 环境,这台机器上任何一个 Python 进程一启动(包括 pip 自己、IDE 的语言服务),它就会去收集 SSH 私钥、云账号凭据、浏览器保存的密码、Claude Code / Codex / Cursor 的登录令牌,以及 LiteLLM 数据库里存的各家大模型 API Key,加密后发走。
LiteLLM 是很多人自建 AI 接口中转、给团队统一管理模型 Key 的首选工具,也被不少 Agent 框架当成依赖。所以就算你没有直接装过它,也值得花 5 分钟查一下。这篇按官方事故公告、GitHub 上的安全 Issue 和 SafeDep 的分析报告整理,给出不启动 Python 的自查命令(我们在自己的 Linux 机器上实测过)和中招后的处置顺序。资料查阅于 2026-10-22 上午,事件还在调查中,后续以官方公告为准。

先看结论:你中招了吗
| 你的情况 | 结论 |
|---|---|
| 10 月 21 日 19:39–21:23(北京时间) 之间用 pip / uv 装或升级过 litellm,没有锁版本 | 很可能装到了 1.107.0,按下文自查 |
用 Docker 跑 LiteLLM 代理,镜像标签是 latest、main-latest、main-stable 或 v1.107.0,并在 19:46–22:20 之间拉取或重启过 |
官方要求按已中招处理 |
依赖里写的是 litellm>=… 这种宽松范围(比如 crewai[litellm] 要求 >=1.88.6,<2),那段时间重建过环境或跑过 CI |
也可能被带进来,同样要查 |
| 一直锁定在 1.106.2 或更早的明确版本 | 不受这次投毒影响 |
| LiteLLM 企业版私有镜像仓库的用户 | 官方说明不受影响 |
官方确认只有 1.107.0 这一个版本有问题,1.106.2 以及 1.107.0rc1、rc2 都是干净的;GitHub 上 v1.107.0 这个源码标签本身也不含恶意文件。截至 10 月 22 日上午,PyPI 上 litellm 的最新版仍是 1.106.2,1.107.0 已被撤下,官方暂停了所有新版本发布,建议大家先锁定 litellm==1.106.2。
它会偷什么
根据 SafeDep 对安装包的解包分析和 GitHub Issue 里贴出的解码代码,1.107.0 的 7 个 wheel 包(Linux、macOS、Windows 全平台)都会往 site-packages 根目录放三个文件:
cook.pth:只有一行import cook。Python 启动时会自动执行.pth里以 import 开头的行,所以不需要你 import litellm,任何 Python 进程启动都会触发。cook.py:凭据窃取程序,收集完加密打包,发到仿冒域名www.litellm.dev(注意不是官方的 litellm.ai)。sitecustomize.py:后门。它会在后台起一个守护进程,每小时去一个 GitHub 仓库读取服务器地址,再下载代码执行。这个 GitHub 账号在事发约两小时后已被删除,但在那之前跑起来的机器可能已经执行过第二阶段代码。
窃取范围很广,按类别归纳一下:
| 类别 | 具体内容 |
|---|---|
| 系统与网络 | 主机名、用户名、IP、路由、监听端口 |
| 浏览器 | Chrome 系保存的密码(会解密)、Cookie、历史;Firefox 的 logins.json 和 key4.db |
| 密钥文件 | ~/.ssh/*、GPG 密钥、TLS 私钥、家目录下的 .pem .key .pfx 等 |
| 命令历史 | bash、zsh、PowerShell、cmd 的历史记录 |
| 云与开发凭据 | AWS、Azure、gcloud、kubeconfig、Docker、gh 登录信息、rclone、.netrc、.git-credentials、.npmrc、.pypirc、.env 文件 |
| CI/CD | GitLab Runner、Jenkins、Vault、Terraform 的凭据,K8s 服务账号令牌 |
| AI 工具 | Claude Code、Claude Desktop、Cursor、Windsurf、Copilot、VS Code 的 mcp.json、Gemini CLI、Codex 的 auth.json、Aider、OpenCode、Qwen、Kiro、Hugging Face 令牌等 |
| LiteLLM 数据库 | 读取 DATABASE_URL,导出存放各家模型 API Key 的两张表 |
| 进程环境变量 | 自身以及(Linux 上)其他进程的环境变量 |
如果你用 LiteLLM 做团队的模型中转,最后两项最要命:DeepSeek、Kimi、OpenAI、Claude 这些上游 Key 和你发给同事的虚拟 Key 都可能已经泄露。
自查:别先跑 pip
官方公告里特别提醒:在可能中招的环境里,不要先跑 pip install 或 pip show。pip 本身就是 Python 程序,一启动就会再执行一次 cook.pth 和 sitecustomize.py。所以第一步应该用系统自带的 find、ls 这类命令直接查文件。
我们整理了一个只读的检查脚本,Linux、macOS 通用,存成 ll_check.sh 后用 sh ll_check.sh 运行(查整机,建议用 sudo,避免权限不足漏掉别的用户目录):
#!/bin/sh
# LiteLLM 1.107.0 投毒自查(只读,不启动 Python)
echo "== 1. 1.107.0 安装痕迹和植入文件"
find / -path /proc -prune -o \( -name 'litellm-1.107.0.dist-info' -o -name 'cook.pth' -o -name 'cook.py' \) -print 2>/dev/null
echo "== 2. site-packages 里的 sitecustomize.py(有就打开看内容)"
find / -path /proc -prune -o -path '*-packages/sitecustomize.py' -print 2>/dev/null
echo "== 3. 标记文件"
ls -la /tmp/.pc_once_72129118c59f5636c0bb /tmp/remote_code_loader.lock 2>/dev/null
echo "== 4. 已安装的 litellm 版本(读 METADATA,不运行 pip)"
find / -path /proc -prune -o -path '*-packages/litellm-*.dist-info/METADATA' -print 2>/dev/null | xargs -r grep -H '^Version:'
echo "== 5. Docker 里的 litellm 镜像"
command -v docker >/dev/null && docker images --digests 2>/dev/null | grep -i litellm
echo "== 完成"
怎么看结果:
- 第 1 步有输出:基本可以确认装过 1.107.0。
- 第 2 步有输出:
sitecustomize.py正常环境里很少见,有的话打开看看,里面出现remote_code_loader或letters9813字样就是后门。 - 第 3 步:
/tmp/.pc_once_…存在说明数据已经发出去了;remote_code_loader.lock存在说明后门守护进程跑过。反过来,这两个文件不在不代表安全,容器重启、清理/tmp都会把它们删掉。 - 第 5 步:如果镜像摘要里出现
sha256:1bbcb1443bc9(官方镜像litellm/litellm)、sha256:c00f9d92c427(litellm-database)或sha256:7b00e91cd2fe(litellm-non_root)开头的,就是被投毒的镜像。
下图是我们在一台 Debian 13 机器上的实测。为了让大家看清“命中”长什么样,我们先在 /tmp/demo-infected 下放了几个同名的空文件模拟中招环境,整机扫一遍大约 2 秒:

Windows 用户可以在 PowerShell 里用下面两条只读命令查(这两条我们没有在 Windows 实机上跑过,只做文件查找,不会改动任何东西;查整个 C 盘会比较慢):
Get-ChildItem C:\ -Recurse -Force -ErrorAction SilentlyContinue -Include cook.pth,cook.py,sitecustomize.py,litellm-1.107.0.dist-info | Select-Object FullName
docker images --digests | Select-String litellm
在 conda、pyenv、uv、pipx 下建过多个环境的人,这个全盘查找比挨个进环境 pip list 更省事,也更安全。
中招了怎么办:按这个顺序
下面的顺序来自官方公告(由最早发现问题的安全研究者 LidorMachluf 整理),我们补充了国内用户常见的几项:
- 先删文件,再动 Python。 在 shell 里直接删掉每个受影响
site-packages里的cook.pth、cook.py、sitecustomize.py,以及__pycache__下对应的cook*.pyc、sitecustomize*.pyc。 - 杀掉后台守护进程。 Linux 上可以用
ps -ef | grep -i python找父进程为 1、工作目录在/的可疑 Python 进程,它持有/tmp/remote_code_loader.lock(lsof /tmp/remote_code_loader.lock能直接看到是谁)。 - 重装锁定版本。 改成
litellm==1.106.2。更稳妥的做法是把虚拟环境和 Docker 镜像整个删掉重建。Docker 用户把镜像写成v1.106.2加摘要锁定,别再用latest;注意官方已经把latest等浮动标签删掉了,写着litellm/litellm:latest的 compose 文件现在会直接拉取失败。 - 默认数据已经外传。 只要这台机器装过 1.107.0 且能上网,就按“已泄露”处理,不要抱侥幸心理。
- 轮换这台机器能碰到的所有凭据:
- LiteLLM 代理数据库里存的每一个上游 Key,以及 master key、发给别人的虚拟 Key;
DATABASE_URL里的数据库密码;- SSH 密钥(生成新的,再把旧公钥从服务器
authorized_keys和 GitHub 上删掉); - GitHub:
gh auth logout后重新登录,并在 GitHub 设置里撤销旧的 OAuth 授权和个人令牌; - Claude Code、Codex、Cursor 等 AI 工具:退出登录再重新登录,各家控制台里的 API Key 全部重建;
- 云账号的 AccessKey、实例角色,以及浏览器里保存过的重要网站密码(邮箱、支付、域名、服务器面板优先)。
- 查有没有被人用过。 AWS 用户官方建议在 CloudTrail 里查安装时间前后的
GetCallerIdentity调用,以及这台机器的角色凭据有没有从外部 IP 被使用。国内云和各家模型平台,可以去控制台看最近的调用量和账单有没有异常。
各家模型平台怎么吊销 Key、看账单、设消费上限,本站之前写过一份 API Key 泄露止损清单,覆盖 OpenAI、Claude、Gemini、DeepSeek 等 8 家,可以照着一家家处理。

这次是怎么被攻破的
LiteLLM 今年 3 月已经出过一次类似事故,之后官方把发布流程收紧了不少:发布放在私有仓库,用 PyPI 的 Trusted Publisher 发布,Docker 标签不可变还带签名。这次攻击者还是绕过去了,按官方事故公告的说明,过程大致是:
- 攻击者拿到了三名工程师的 GitHub CLI 登录令牌,其中一个属于 GitHub 组织所有者。
- 用组织所有者的令牌关掉分支保护,强推了一个改动,让发布流程可以指向别的源码仓库。
- 再用另一名工程师的账号通过生产发布的审批,从一个仿冒仓库
Berri-AI/litellm(正牌是BerriAI/litellm,只差一个连字符)构建、签名并发布了带毒的包和镜像,事后又删掉了工作流记录。
令牌是怎么泄露的,官方目前的判断是:他们发现 Claude Code 在某些情况下会把用户的 GitHub CLI OAuth 令牌带进响应内容里,如果网关记录了完整的响应日志,令牌就会落进 LiteLLM 的日志;而他们内部有一个暴露在公网上的 LiteLLM 实例,里面多了一个名字看起来无害的陌生账号。攻击者很可能是借一个最近才修补的漏洞进了这个实例,从日志里拿到了令牌。这部分官方还在核实。
顺带一提,LiteLLM 9 月 30 日还公布过一个严重级别的权限提升漏洞(GHSA-7hp6-4w63-5g45,普通用户可以提权成代理管理员并执行命令),影响 1.91.0 起的多个版本,修复版本是 1.100.4、1.101.3、1.102.2、1.103.1 等。还在跑老版本代理的,借这次机会一起升级到 1.106.2。
给自建 AI 网关的人几条建议
这次事件对“自己搭一个 AI 中转站”的个人和小团队很有参考价值:
- 版本写死。
requirements.txt里写litellm==1.106.2,有条件再加--require-hashes校验哈希;用 uv、poetry 的话提交 lock 文件。Docker 镜像用@sha256:摘要锁定,不用latest。 - 新版本别第一时间上。 生产环境等新版本发布一两天、社区没报问题再升级,这次的毒包在 PyPI 上只挂了不到两个小时。
- 管理后台不要直接暴露在公网。 不管是 LiteLLM 还是 New API 这类中转站,管理界面最好只在内网、VPN 或 Cloudflare Access 后面访问,定期看一眼用户列表里有没有陌生账号。
- 日志别记完整的请求和响应。 网关日志里很容易混进令牌、密钥和用户隐私,能关就关,必须记的话做脱敏。
- 开发机上的凭据越少越好。 编程 Agent 能读到的目录里尽量别放长期有效的令牌。只是想在 Claude Code、Codex 之间切换模型的个人用户,用 Magpie 这类本机网关就够了,不一定要搭一个对外开放的服务。
时间线(北京时间)
| 时间 | 事件 |
|---|---|
| 10 月 21 日 18:08 | 攻击者用盗来的令牌绕过分支保护,改动私有发布流程 |
| 19:39–19:40 | 7 个带毒的 1.107.0 wheel 上传到 PyPI |
| 19:46 | 带毒的 Docker 镜像发布,latest 等标签指向它 |
| 约 20:06 | 安全研究者在 GitHub 提交安全 Issue |
| 21:23 前 | PyPI 撤下 1.107.0 |
| 21:51 | GHCR 上的受影响标签已不可用 |
| 22:20 | Docker Hub 上的受影响标签全部删除或改指向干净镜像 |
| 10 月 22 日 02:30 | 官方发布事故公告,定性为“已控制,调查中” |
| 10 月 22 日 04:30 | 官方公布初步判断的攻击链,之后每两小时更新一次 |
参考来源
开发者侧要防供应链投毒,日常生活里刷单、杀猪盘同样要长见识:开源整理的 人间防骗指南 有 373 篇骗局拆解与自查清单(遇事仍要核实报警)。


