flawopen.com/AI Security/berriai-litellm-ghsa-7hp6-salt-key-session-token-privilege-escalation
LiteLLM:salt key 重用导致权限提升(GHSA-7hp6)
LiteLLM 将同一加密路径用于存储密钥和 UI、CLI 会话令牌。已认证的 internal_user 可让其控制的身份数据经过该路径并获得 proxy_admin;该角色可访问 MCP stdio 命令执行。修复使用专用前缀和经过认证的 AES-GCM 上下文绑定令牌用途。公告未列出 CVE,也未确认现实攻击中的利用。[1], [2]
一栋楼用同一枚印章封存储信封并签发管理员门禁卡。访客可以影响信封内容,门卫随后却把它当成真的门禁卡。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]
框架映射
- FlawOpen 对 MITRE CWE 的概念性映射;没有厂商或 CVE 记录将此弱点编号分配给本研究演示。 CWE-345
攻击执行流程分解
低权限账户访问密钥管理功能
公告规定的起始条件是已认证的 internal_user。无需匿名访问,但攻击者必须已经拥有该角色。[1]
管理权限可触达 MCP stdio
公告称,proxy_admin 可通过 MCP stdio 端点执行命令。这是主机上的进程能力,并非模型本身执行命令。[1]
根本原因剖析 (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
)
工程与系统安全加固清单
- ✓将每个 LiteLLM 部署升级到对应分支的修复版本,并确认实际解析出的包或镜像版本,不要仅依赖可变标签。[1], [3], [4]
- ✓对于 1.87.0–1.90.x,检查是否启用了 EXPERIMENTAL_UI_LOGIN;公告称这些版本只有在该设置开启时受影响。[1]
- ✓若无法立即升级,可临时设置
EXPERIMENTAL_UI_LOGIN=false,并安排处理 CLI SSO 与 Claude Code gateway 登录功能中断。[1] - ✓添加回归测试:会话解码器必须拒绝存储值密文,同时仍接受有效且未过期的会话令牌。[2]
- ✓绑定密文用途:签发和验证时都将令牌前缀作为 AES-GCM AAD 认证;不要把通用解密结果当成身份令牌。[2]
- ✓仅允许必要角色管理密钥和配置 MCP stdio,并以最小操作系统权限运行 proxy。[1]
- ✓FlawOpen 分析:为部署环境的身份验证审计添加埋点,记录主体、解析出的角色、令牌类型、时间戳和请求 ID,但不记录 bearer token 或密文;并测试事件结构。添加告警测试,检测 LiteLLM 代理进程启动 MCP stdio 子进程的情况;调查时关联身份验证和进程事件。这些是部署侧检测建议,并非供应商确认存在的日志信号。
- ✓按 GHSA-7hp6-4w63-5g45 跟踪:公告未列出 CVE,现有来源也未确认现实攻击中的利用。[1]
参考来源
- BerriAI LiteLLM security advisory GHSA-7hp6-4w63-5g45
- LiteLLM upstream session-token fix f7cd90f
- LiteLLM v1.100.4 release notes: UI and CLI session-token format
- LiteLLM v1.104.0 release notes: session-token format and upgrade behavior
- MITRE CWE-345: Insufficient Verification of Data Authenticity
- MITRE CWE-269: Improper Privilege Management
- MITRE CWE-441: Unintended Proxy or Intermediary