这项研究以 Pwn2Own Berlin 2026 的 LiteLLM 目标为背景,记录了研究过程中围绕四个连续版本构造完整利用链的过程。随着漏洞被修复和攻击面发生变化,利用思路也从认证绕过、权限提升逐步演变到新的信息泄露与代码执行路径。
利用链演进
- LiteLLM 1.82.3:从数据库异常处理与认证逻辑切入,组合模板注入或 Python 沙箱逃逸实现代码执行。
- LiteLLM 1.83.7:利用元数据校验缺口、路由前缀匹配和用户角色更新问题,从低权限用户提升至代理管理员。
- LiteLLM 1.83.10:围绕 onboarding token 与团队邀请权限重新构造提权路径。
- LiteLLM 1.83.14:通过未被完整覆盖的环境变量访问路径与响应通道完成敏感信息获取。
文章重点不仅是单个漏洞,也包括补丁变化如何影响攻击链,以及研究人员如何根据新的代码路径持续调整利用策略。
阅读原文
完整的技术分析、代码片段、利用过程与补丁时间线请阅读 STAR Labs 原文:
Race Against The Patch: The Evolution of Four Exploit Chains in LiteLLM ↗
2026/07/28 更新
今天整理笔记的时候发现之前的 4 chain 文章遗漏了之前挖到的一个漏洞,场景是是不需要任何user key, 但是需要服务器上有可利用的 MCP server。( 因为p2o 不允许提前安装 MCP 这个方案后面就被放弃了)
这里简单补充一下
Bug 1:一个出现在查询串里的 .well-known
LiteLLM 需要公开 OAuth 元数据发现端点,因此旧代码加入了下面的放行条件:
1 | if ".well-known" in str(request.url): |
问题在于,这不是对路由进行匹配,而是在完整 URL 中搜索一个子串。查询字符串、额外路径段甚至 Host 部分只要出现 .well-known,都可能被认证层误认为公开端点。
1 | POST /mcp/ → 未认证请求被拒绝 |
攻击者实际上没有访问 OAuth 元数据路由,却得到了相同的空 UserAPIKeyAuth() 对象。
Bug 2:失败的 Bearer Token 反而换来匿名身份
第二条路径来自 OAuth2 兼容逻辑:
1 | elif oauth2_headers: |
请求只要携带任意 Authorization 头,就会进入该分支。如果 Bearer Token 校验返回 401 或 403,处理器不会拒绝请求,而是将认证结果降级为空身份。
1 | 无 Authorization 头 |
也就是说,一个明显无效的 Token 反而成为了继续执行请求的条件。这是典型的 fail-open:系统无法确认调用者身份时,没有终止请求,而是猜测调用者可能正在使用另一套上游 OAuth2 凭据。
从认证绕过到工具调用
空身份本身并不是代理管理员,但下游 MCP Server 选择逻辑会把 allow_all_keys: true 的服务器加入可访问集合。完整利用路径因此非常短:
1 | 未认证请求 |
最终影响完全由已经注册的工具决定。查询类工具可能泄露业务数据,文件或数据库工具可能读写敏感信息,内部 HTTP 工具可能形成内网访问;如果管理员注册了命令执行类工具,认证绕过才可能进一步组成 RCE。
相关漏洞官方也已经修复了
// EXTERNAL_CHANNEL
评论