1. 事件复盘:litellm 投毒到底是怎么发生的
1.1 先搞明白 litellm 在我们的架构里是什么角色
litellm 说白了就是大模型时代的“流量网关”。不管你是接 OpenAI、Anthropic、Azure 还是本地部署的 Ollama,只要走 litellm proxy,上层业务只认这一个地址,底层模型随便换。这也是为什么 litellm 在近两年火得快,很多团队直接把它当公司内部的模型代理底座来用。
问题恰恰出在这个位置。普通的开源库被投毒,顶多是你某个功能不好使,或者数据被偷走一部分。但 litellm proxy 这一层被投毒,相当于你公司所有模型请求的“总水管”被人接了一根暗管。请求要经过它、API Key 存在它那里、日志从它这边出去,甚至连模型路由规则都由它决定。这层要是失守,就不只是丢一两个 Key 的事,而是模型调用、业务数据、内部逻辑全部暴露在攻击者眼皮底下。
这次事件在群里传开的时候,大家用的关键词就是“litellm 投毒”和“账号投毒事件(mini shai-hulud 蠕虫)排查通知”。我先解释一下大概发生了什么:攻击者没有去硬刚 litellm 官方仓库,而是通过各种方式诱导你安装被篡改过的依赖包、仿冒的同名包,或者在拉取镜像时拿到带后门的版本。一旦装上,恶意代码就开始扫描环境变量、读取代理配置文件、尝试把密钥和日志转发到外部服务器。
1.2 投毒的几个主要入口,别以为只有 pip install 才危险
很多人一听到“投毒”,第一反应是“我又没乱装包,不怕”。实际上这次 litellm 投毒的传播路径比想象中要宽,我把目前已知的几类入口梳理了一下:
| 投毒入口 | 典型场景 | 危险程度 |
|---|---|---|
| PyPI 仿冒包 | 用 litellm、liteLLM、llitellm 等相似名字发布恶意包,等人拼错装错 | 高 |
| 传递依赖被劫持 | litellm 正常,但它的某个子依赖上游被替换成恶意版本 | 很高 |
| Docker 镜像投毒 | 拉取 litellm proxy 镜像时用了非官方源或被篡改的 tag | 很高 |
| 内部源混入问题包 | pip 配置了私有源,私有源同步时没有做完整性校验 | 高 |
| 配置下发劫持 | 攻击者通过配置中心或环境变量注入恶意 model tag | 中等 |
这里特别要提醒的是“传递依赖被劫持”这条链路。litellm 本身的依赖树不算小,有 openai、anthropic、requests、pydantic 这些常见的包,任何一个上游出错都会顺着依赖关系进入你的环境。平时大家安装 litellm 时会看到一堆依赖一起装进来,没人会逐个检查这些包最近有没有发过带问题的版本。攻击者只要在某个依赖的某个版本里塞一段采集环境变量的代码,就能顺藤摸瓜拿到你在 .env 里写的那些 Key。
1.3 “标签投毒”这步操作,是这次事件里最阴的地方
这次排查通知里反复出现一个词叫“标签投毒”。我第一次看到的时候也没反应过来,后来仔细一看,才发现这个攻击思路确实刁钻。
litellm proxy 支持给模型设置别名、标签、负载均衡策略,比如“team-a-model”指向 gpt-4o,“team-b-model”指向 claude-sonnet。攻击者投毒之后,不直接改你的代码,而是去改模型配置数据库或部署文件里的标签映射关系。这样做的效果是:你以为自己在调公司内部最便宜的那个模型做测试,实际流量已经被悄悄导到攻击者控制的服务器上。你发的 prompt、传进去的业务数据,全经过别人的手。
这种攻击最难防的一点是,它不会让系统报错,也不会让接口突然变慢。你只会在月底对账的时候发现某个模型的调用量对不上,或者某些“明明没有调用记录”的数据泄露出去。但因为走的是同一个 litellm 入口,日志可能还被攻击者抹掉了一部分,查起来特别费劲。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 自查清单:怎么快速判断机器中招了没有
2.1 检查安装来源和依赖树,这一步别跳
收到排查通知之后,第一件事不是去看流量监控,而是先把你机器上装的那个 litellm 是从哪来的、装的是什么版本。先跑一遍这几条命令看看现状:
bash复制# 查看 litellm 当前版本和安装路径
pip show litellm
# 列出完整依赖树,确认是否有可疑的包
pip show litellm | grep -E "Version|Location"
pipdeptree -p litellm
如果 pipdeptree 没装,可以用 pip freeze 先看个大概:
