FlawOpen

flawopen.com/AI Security/berriai-litellm-ghsa-7hp6-salt-key-session-token-privilege-escalation

● FlawOpen 映射: CWE-345 · CVSS 9.9 · 严重
安全研究 · FlawOpen

LiteLLM:salt key 重用导致权限提升(GHSA-7hp6)

LiteLLM 将同一加密路径用于存储密钥和 UI、CLI 会话令牌。已认证的 internal_user 可让其控制的身份数据经过该路径并获得 proxy_admin;该角色可访问 MCP stdio 命令执行。修复使用专用前缀和经过认证的 AES-GCM 上下文绑定令牌用途。公告未列出 CVE,也未确认现实攻击中的利用。[1], [2]

💡 通俗易懂的原理解析 (ELI5)

一栋楼用同一枚印章封存储信封并签发管理员门禁卡。访客可以影响信封内容,门卫随后却把它当成真的门禁卡。LiteLLM 的修复为会话卡增加专用标记,并在密码学上将标记与印章绑定。[1], [2]

核心概念与专有名词

Salt key
LiteLLM 配置的加密密钥材料。该问题在不同用途间复用同一密钥路径,却没有把密文与预期用途绑定。[1], [2]
认证附加数据(AAD)
AES-GCM 与密文一起认证的数据,例如令牌类型前缀。数据被更改或缺失时,认证会失败。[2]
internal_user 与 proxy_admin
LiteLLM 的角色。公告称已认证的 internal_user 可提升为管理角色 proxy_admin。[1]
MCP stdio
Model Context Protocol 传输方式,可启动本地进程并通过标准输入输出通信。公告称 proxy_admin 可经此端点执行命令。[1]
CWE-345
对数据真实性验证不足。此处是 FlawOpen 选定的主要编辑分类;公告还列出 CWE-269 与 CWE-441。[1], [5], [6], [7]

框架映射

  • FlawOpen 对 MITRE CWE 的概念性映射;没有厂商或 CVE 记录将此弱点编号分配给本研究演示。 CWE-345

攻击执行流程分解

步骤 1

低权限账户访问密钥管理功能

公告规定的起始条件是已认证的 internal_user。无需匿名访问,但攻击者必须已经拥有该角色。[1]

步骤 2

metadata 经共享路径生成密文

公告称,密钥 metadata 中受控的身份数据可能被加密并返回。问题在于随后把该密文接受为另一种令牌。[1], [2]

步骤 3

会话解析器接受了用途不同的密文

修复前,值加密和会话验证共用 helper 与密钥路径,且没有认证令牌用途。身份数据可能被解析为 proxy_admin。[1], [2]

步骤 4

管理权限可触达 MCP stdio

公告称,proxy_admin 可通过 MCP stdio 端点执行命令。这是主机上的进程能力,并非模型本身执行命令。[1]

步骤 5

用途绑定拒绝跨用途重用

修复以 litellm_login_ 作为 AES-GCM AAD,并使用专用解码器。升级到已修复版本;关闭 EXPERIMENTAL_UI_LOGIN 仅是有功能影响的临时措施。[1], [2], [3], [4]

根本原因剖析 (Root Cause)

BerriAI 的 GHSA-7hp6-4w63-5g45 公告描述了认证用途混淆。LiteLLM 对存储密钥和 UI/CLI 会话令牌使用同一值加密 helper,会话认证也沿用同一密钥路径解密。已认证的 internal_user 可请求一个 API key,在 metadata 中放入其控制的序列化身份数据;管理路径加密并返回该值。若将密文作为 bearer token 提交,会话路径可能解密它,并将伪造身份解释为 proxy_admin,从而访问 MCP stdio 命令执行。上游修复 f7cd90f 改变令牌创建与验证方式:使用 litellm_login_ 前缀、绑定该前缀的 AES-GCM AAD,以及专用解码器。salt key 仍是密钥材料;这里验证到的安全边界是经过认证的令牌用途和匹配的解码器。存储值密文因此无法作为会话令牌通过验证。公告标注 CVSS 3.1 9.9 Critical;1.91.0 之后的版本默认受影响,1.87.0–1.90.x 仅在 EXPERIMENTAL_UI_LOGIN=true 时受影响。各分支列出的修复版本为 1.100.4、1.101.3、1.102.2、1.103.1 和 1.104.0rc2。临时措施 EXPERIMENTAL_UI_LOGIN=false 会关闭易受影响的登录路径,但也会影响 CLI SSO 和 Claude Code gateway 登录。公告没有 CVE,也未确认现实攻击中的利用。代码对比展示上游认证用途边界的变化,不是漏洞利用代码,也不是完整认证实现。[1], [2], [3], [4]

源代码对比:漏洞与安全实现

上游修复在会话令牌创建与认证时替换通用值加密和解密 helper。encrypt_bearer_token 将前缀作为 AES-GCM AAD 认证;decrypt_bearer_token 要求相同前缀和 AAD。因此存储值密文不能作为登录令牌使用。这是所引提交的简化代码片段,并非独立认证实现。 共享的 salt 密钥本身不能证明每种用途都使用独立密钥;这里能确认的隔离来自经过认证的令牌类型和匹配的解码器。[2], [3]

源码摘录: litellm/proxy/auth/auth_checks.py 和 litellm/proxy/common_utils/encrypt_decrypt_utils.py — 上游 commit f7cd90f 的简化代码片段

存在漏洞的实现
# 修复前:存储值的密文也会被签发为会话令牌。
return encrypt_value_helper(valid_token.model_dump_json(exclude_none=True))

# 会话认证通过通用值 helper 解密令牌。
decrypted_token = decrypt_value_helper(hashed_token, key="ui_hash_key")
加固后的安全修复
# 修复后:会话令牌具有专用类型和 AAD。
LITELLM_SESSION_TOKEN_PREFIX = "litellm_login_"
return encrypt_bearer_token(
    valid_token.model_dump_json(exclude_none=True),
    prefix=LITELLM_SESSION_TOKEN_PREFIX,
)

# 认证过程使用与该用途匹配的解码器。
decrypted_token = decrypt_bearer_token(
    hashed_token, prefix=LITELLM_SESSION_TOKEN_PREFIX
)

工程与系统安全加固清单

参考来源

← AI Security Directory →