Compromised LiteLLM 1.107.0 on PyPI Installs a Credential Stealer and Backdoor
Compromised LiteLLM 1.107.0 on PyPI Installs a Credential Stealer and Backdoor
Protect your projects from malicious packages. 保护您的项目免受恶意软件包的侵害。
The LiteLLM 1.107.0 release on PyPI carries a credential stealer and a remote code execution backdoor. All seven wheels (Linux, macOS, Windows) install them as three files in site-packages. Both run when any Python process starts on the host, even one that never imports litellm. The upstream GitHub source does not contain them. PyPI has since removed the release. PyPI 上的 LiteLLM 1.107.0 版本携带了一个凭据窃取程序和一个远程代码执行后门。所有七个 wheel 包(Linux、macOS、Windows)都会将它们作为三个文件安装到 site-packages 中。无论主机上的 Python 进程是否导入了 litellm,只要该进程启动,这两个恶意程序就会运行。上游 GitHub 源码中并不包含这些文件。PyPI 现已删除了该版本。
Versions 1.106.2, 1.107.0rc1, and 1.107.0rc2 are clean. The companion packages that 1.107.0 pins, litellm-proxy-extras==0.4.110 and litellm-enterprise==0.1.78, are also clean. 1.106.2、1.107.0rc1 和 1.107.0rc2 版本是干净的。1.107.0 所锁定的配套软件包 litellm-proxy-extras==0.4.110 和 litellm-enterprise==0.1.78 也同样是干净的。
Installing litellm==1.107.0 places three files in site-packages. Python loads two of them each time it starts. 安装 litellm==1.107.0 会在 site-packages 中放置三个文件。Python 每次启动时都会加载其中的两个。
The pyproject.toml in the 1.107.0 source distribution (sdist) has one extra line in the maturin build section: 1.107.0 源码分发包(sdist)中的 pyproject.toml 在 maturin 构建部分多出了一行:
The maturin data = “cook” setting copies a cook/ folder into litellm-1.107.0.data/purelib/ in the wheel. pip installs that folder into site-packages. maturin 的 data = “cook” 设置会将一个 cook/ 文件夹复制到 wheel 包的 litellm-1.107.0.data/purelib/ 中。pip 会将该文件夹安装到 site-packages 中。
The sdist leaves out the cook/ folder, so this line is the only visible change. No public commit in BerriAI/litellm contains data = “cook” or a cook/ folder. sdist 中并未包含 cook/ 文件夹,因此这一行是唯一可见的改动。BerriAI/litellm 的任何公开提交中都不包含 data = “cook” 或 cook/ 文件夹。
The wheel RECORD lists the three added files: wheel 的 RECORD 文件列出了这三个新增文件:
The tag v1.107.0 points to commit 66c8f5b (06:59 UTC). Its pyproject.toml says version = “1.108.0”. SafeDep compared every sdist file with the git trees by blob hash. The sdist matches a later main commit, a8113b0 (08:50 UTC), plus five edited files and the cook/ folder. 标签 v1.107.0 指向提交 66c8f5b(UTC 时间 06:59)。其 pyproject.toml 显示版本为 “1.108.0”。SafeDep 通过 blob 哈希值将每个 sdist 文件与 git 树进行了比对。该 sdist 与后续的一个主分支提交 a8113b0(UTC 时间 08:50)相匹配,外加五个被编辑的文件和 cook/ 文件夹。
Four of the edited files are Cargo.toml files that gain a readme = “README.md” line. The legitimate 1.106.2 and rc2 releases have the same edit. The fifth is pyproject.toml, compared here with a8113b0: 其中四个被编辑的文件是 Cargo.toml,它们增加了一行 readme = “README.md”。合法的 1.106.2 和 rc2 版本也有相同的改动。第五个文件是 pyproject.toml,此处与 a8113b0 进行了对比:
The edit sets the version back to 1.107.0 and pins the companion packages to the rc2 values. As a result, a dependency diff against rc2 shows nothing unusual. The legitimate 1.106.2 sdist matches its tag commit 49943cd except for the Cargo.toml readme lines. 该改动将版本改回了 1.107.0,并将配套软件包锁定为 rc2 的值。因此,与 rc2 进行依赖项差异对比时未发现异常。合法的 1.106.2 sdist 除了 Cargo.toml 的 readme 行外,与其标签提交 49943cd 一致。
The malicious wheels match the output of the normal BerriAI release pipeline: 这些恶意 wheel 包与正常的 BerriAI 发布流水线的输出相符:
No public GitHub Actions run built or published the release. SafeDep checked all 539 runs between 09:30 and 12:30 UTC. At 11:50 UTC, about 10 minutes after the PyPI upload, litellm-dispatcher[bot] published the GitHub release v1.107.0. The same delay occurred for 1.106.2. PyPI has no provenance attestations for 1.107.0, 1.106.2, or rc2. 没有任何公开的 GitHub Actions 运行记录构建或发布了该版本。SafeDep 检查了 UTC 时间 09:30 到 12:30 之间的所有 539 次运行。在 UTC 时间 11:50(即 PyPI 上传约 10 分钟后),litellm-dispatcher[bot] 发布了 GitHub 版本 v1.107.0。1.106.2 版本也出现了同样的延迟。PyPI 上没有 1.107.0、1.106.2 或 rc2 的来源证明。
SafeDep assesses, with moderate to high confidence, that BerriAI’s private release pipeline built these wheels from an attacker-modified git source. The attacker could have used a compromised maintainer or bot credential, a private branch or mirror, or the reference the pipeline builds from. A stolen PyPI token used from the attacker’s own machines fits the evidence less well. Only BerriAI’s pipeline logs can confirm the cause. SafeDep 以中等到较高的置信度评估认为,BerriAI 的私有发布流水线是基于攻击者修改过的 git 源码构建了这些 wheel 包。攻击者可能使用了被入侵的维护者或机器人凭据、私有分支或镜像,或者是流水线所构建的引用。从攻击者自己的机器上使用被盗的 PyPI 令牌这一假设与证据不太吻合。只有 BerriAI 的流水线日志才能确认原因。
At startup, Python runs each line that starts with import in a .pth file in site-packages. cook.pth contains import cook, so the stealer runs in every Python process on the host: the application, pip, IDE language servers, and CI jobs. 在启动时,Python 会运行 site-packages 中 .pth 文件里每一行以 import 开头的代码。cook.pth 包含 import cook,因此窃取程序会在主机上的每个 Python 进程中运行:包括应用程序、pip、IDE 语言服务器和 CI 作业。
cook.py wraps about 61 KB of Python in one layer of exec(zlib.decompress(base64.b64decode(’…’))). The decoded code starts with this configuration: cook.py 将约 61 KB 的 Python 代码封装在了一层 exec(zlib.decompress(base64.b64decode(’…’))) 中。解码后的代码以以下配置开头:
Python imports sitecustomize at startup, so this file also runs in every Python process. Python 在启动时会导入 sitecustomize,因此该文件也会在每个 Python 进程中运行。
The attacker can point the daemon at a new server by editing domain.txt. Each infected host runs whatever that server returns as codepy. 攻击者可以通过编辑 domain.txt 将守护进程指向新的服务器。每个受感染的主机都会运行该服务器返回的任何 codepy 代码。
At 13:40 UTC, the GitHub account letters9813 and its repository returned 404, about two hours after the release. The backdoor now finds no server address and does nothing. Hosts that ran the daemon before the deletion could have received and run second-stage code. SafeDep could not recover the server address. UTC 时间 13:40,即发布约两小时后,GitHub 账户 letters9813 及其存储库返回了 404 错误。后门现在找不到服务器地址,因此不再执行任何操作。在删除之前运行过该守护进程的主机可能已经接收并运行了第二阶段代码。SafeDep 无法恢复该服务器地址。
All times are UTC on 2026-10-21. 所有时间均为 2026 年 10 月 21 日的 UTC 时间。
The planted files have different hashes on Windows because of the CRLF line endings: 由于 CRLF 换行符的原因,植入的文件在 Windows 上的哈希值不同:
Follow for the latest updates and insights on open source security & engineering. 关注以获取有关开源安全与工程的最新更新和见解。
An attacker pushed forged commits to the default branches of hugo-paper and mevn-cli. Running npm install or bun install in either repository downloads and runs a second-stage script from… 攻击者向 hugo-paper 和 mevn-cli 的默认分支推送了伪造的提交。在任一存储库中运行 npm install 或 bun install 都会下载并运行来自……的第二阶段脚本。
Attackers got into the platforms ASOS uses to message customers and pushed an extortion note to phones. Here is what is confirmed, what is only claimed, and what customers should do. 攻击者入侵了 ASOS 用于向客户发送消息的平台,并向手机推送了勒索信息。以下是已确认的内容、仅被声称的内容以及客户应采取的措施。
The MALFEX package imgdecode contains a native Windows loader. When loaded from a console, it attempts to download, decrypt, and inject shellcode into dllhost.exe. MALFEX 软件包 imgdecode 包含一个原生的 Windows 加载程序。当从控制台加载时,它会尝试下载、解密并将 shellcode 注入到 dllhost.exe 中。
[email protected] on npm ran a Mini Shai-Hulud worm at install. A maintainer account committed the payload through the GitHub web interface, and the official release workflow published it. npm 上的 [email protected] 在安装时运行了一个 Mini Shai-Hulud 蠕虫。一个维护者账户通过 GitHub Web 界面提交了有效载荷,并由官方发布工作流进行了发布。
Start free with open source tools on your machine. Scale to a unified platform for your organization. 在您的机器上免费使用开源工具开始。扩展至适合您组织的统一平台。
SafeDep keeps analytics anonymous and cookie-free until you opt in. Accepting helps us understand product usage and improve your experience. Privacy Policy 在您选择加入之前,SafeDep 会保持分析匿名且无 Cookie。接受有助于我们了解产品使用情况并改善您的体验。隐私政策
Choose what you share. You can change this anytime from the footer. 选择您要共享的内容。您可以随时从页脚更改此设置。