ARTICLE · 1239721
AI 网关可能正在把你的密钥送给别人
10 月 21 日凌晨,LiteLLM 这个被大量团队当成 AI 网关的开源 Python 包,在官方发布流程里被人塞进了偷凭据的木马。它以 1.107.0 的版本号同时出现在 PyPI 和 Docker Hub 上,存活时间不长,PyPI 上大概 1 小时 44 分,容器镜像大概 2 小时 34 分。但凡这段时间里装过它的机器,密钥可能已经不在你手里了。
说人话:出了什么事
LiteLLM 干的事是给一百多家模型厂商做统一入口。你调一次接口,它帮你路由到 OpenAI、Claude、Gemini 或者本地模型,顺便替你保管所有厂商的 key。
10 月 21 日凌晨,攻击者用三个工程师的 GitHub CLI OAuth token 改掉了它的私有发布流程,然后从这个流程里推了一个看起来完全正常的 1.107.0 出来。
关键在构建源。真的官方仓库叫 BerriAI/litellm,假的叫 Berri-AI/litellm,差一个连字符。所以 GitHub 上 v1.107.0 那个源码 tag 是干净的,你翻遍代码也看不出问题,但 pip install 下来的是有毒的。
你更担心的是那一个半小时,还是"我根本不知道机器上装过什么"?
哪里不一样了
过去几年 AI 工具出事的套路,是某个客户端自己有毛病,攻击者从外面打进来。这次顺序反过来了:出事的是发布流水线本身,官方版本号、官方仓库、官方 Docker 镜像,全都正常,毒是从里面长出来的。
三个被偷的 token 各管一段。第一段用来关掉分支保护,把改动硬推上去。第二段负责在生产审批环节点通过。第三段把生产和预发布环境的工作流记录删掉,调查的人事后能看到的东西少了很多。
恶意代码藏在三个文件里:cook.pth、cook.py、sitecustomize.py。这三个都是 Python 启动时自己会去读的东西,所以不需要你 import LiteLLM,只要机器上开过任何一次 Python,代码就跑起来了。pip、测试脚本、IDE 的后台服务,全都算。
一个开源包能骗过多少人的"我 GitHub 上看着是好的"这个判断,你现在有概念了吗?
几个容易忽略的细节
被偷走的东西比"模型 API key"多得多。
cook.py 那个窃取器扫的是浏览器存的密码、shell 历史、云凭据、云厂商实例元数据里的角色凭据、Kubernetes 的 service account token、CI 里的密钥、SSH 私钥、GPG 私钥、TLS 私钥、Git 和 npm 和 PyPI 的令牌、所有进程的 .env 和环境变量,还有二十多种 AI 编程工具的凭据,Claude Code、Cursor、Copilot、Gemini CLI、Codex、Hugging Face 全在名单里。
还有一层:sitecustomize.py 会另起一个后台进程,每小时去一个 GitHub 上的死信仓库看有没有新文件,有就下载下来执行。等于留了一个长期后门,就算你把三个文件删了,守护进程还在。
传输用的是 AES-256 加 RSA-4096 加密,发到 www.litellm[.]dev 下面的一个 healthcheck 路径。这个域名在发布前一周就注册好了。
泄露到被滥用之间有多快?Wiz 的观测是大概 4 个半小时。已经开始有人在调 AWS 的 sts:GetCallerIdentity,还在列举 Bedrock 里的模型清单。
4 个半小时这个数字,你觉得够不够你去轮换一遍密钥?
这跟你有什么关系
第一,先确认你有没有中招。这个攻击只针对 1.107.0,PyPI 上的包活了约 1 小时 44 分,容器镜像从 11:46 到 14:20 UTC,约 2 小时 34 分。浮动标签 latest、main-latest、main-stable 那段时间指向的都是被污染的镜像,所以"我 pull 的不是 1.107.0"这句话不成立,你得对 digest。
第二,就算你没装过 LiteLLM,也可能被殃及。这次泄露路径的起点是 LiteLLM 官方自己的一套内部部署,那套部署意外暴露在公网上,日志里记录了 Claude Code 的响应体,而 Claude Code 会把用户的 GitHub CLI OAuth token 嵌进响应体里。日志进了网关,token 就被捡走了。攻击面不限于"你装了 LiteLLM"这件事本身。
第三,LiteLLM 在 2026 年 3 月已经被投毒过一次,那次是 1.82.7 和 1.82.8。这次手法相似,第三方安全公司 Socket 说没有证据证明是同一批人,嵌入的 RSA 公钥和外传实现都不一样,但也不排除同一个人换了工具。
你手上有多少个 AI 工具的 token,能在十分钟之内全部轮换完?
你现在能怎么用
处置第一步很反直觉:不要先跑 pip。官方明确说了,在受污染的环境里跑任何一次 Python 都会把那几个文件再执行一遍,等于帮攻击者续命。
正确顺序是:先断网隔离这台机器,保留现场证据;再删掉 cook.pth、cook.py、sitecustomize.py 及其 pycache 副本;再杀掉持有 /tmp/remote_code_loader.lock 的游离守护进程;然后从干净设备上轮换所有凭据,包括云厂商、代码托管、npm、PyPI、CI 密钥,以及那二十多个 AI 工具;最后重建镜像和虚拟环境,版本钉到 1.106.2 或更早。1.107.0rc1 和 1.107.0rc2 是干净的。
如果你的部署用的是私有企业版 LiteLLM,官方说那条线没有受影响。
往后加一道工序:固定版本加哈希校验,别用浮动标签。官方这次的反应是移除了组织里除一名未受影响用户之外的所有人,并解除了公开仓库与镜像仓库之间的信任链接。
你今天会先去查一遍自己机器上装了哪些 AI 工具的中间件,还是先想着"这事离我很远"?
我的看法
这次最难防的地方不在技术,在习惯。我们判断一个包干不干净,靠的是"它是不是官方发布的",而这次官方发布了。GitHub 源码干净,tag 是对的,版本号没造假,Docker Hub 上挂的也是他的官方组织。你原来用来做判断的信号全部通过了。
唯一的破口是构建源。BerriAI 和 Berri-AI 差一个连字符这件事,攻击者提前注册了域名、提前搭好了发布流程、提前想好了怎么用三个被偷的 token 分工。这个准备时间不是一天做出来的。
所以真正该改的判断标准是:不要问"这个包是不是官方的",要问"我装的这一个字节是不是官方构建出来的那一串字节"。前者靠信任,后者靠校验。
还有一个容易被忽略的点。攻击者一次用了三个工程师的 token,说明至少三个人的环境里出过问题。任何一个把个人开发机上的 token 当生产凭据用的团队,都要重新想一遍。
你觉得下一个被投毒的开源包,会出现在 AI 工具这一层,还是在更传统的地方?
最后聊一句:这期几篇里你最想看哪一篇的后续,或者你有什么不同看法,评论区说出来,我挑有代表性的写进下一期。觉得有用的话,点一下「在看」,能让更多人看到。
LiteLLM供应链攻击开源安全密钥泄露北科信息















































































