漏洞概述
LiteLLM 是一个开源的大语言模型代理网关(46.5k+ Stars),支持统一接口调用 OpenAI、Anthropic、Azure 等 100+ LLM 提供商。其 Proxy 模式使用 PostgreSQL 存储 API Key、团队配置及提供商凭据等敏感数据。
近期,LiteLLM Proxy 的 API Key 认证流程中被发现存在一个预认证 SQL 注入漏洞。攻击者无需任何有效凭据,仅通过发送构造的 `Authorization` 头即可触发注入,读取甚至篡改代理数据库中的所有数据,包括全部 LLM 提供商的 API Key。(网宿评分:极危、CVSS 3.0 评分:9.8)
目前该漏洞POC状态已在互联网公开,建议客户尽快做好自查及防护。
受影响版本
1.81.16 <= LiteLLM < 1.83.7
漏洞分析
- 前置知识:LiteLLM Proxy 的 API Key 认证流程
LiteLLM Proxy 启用 API Key 认证后,所有 LLM API 路由(如 `/chat/completions`)都需要在请求头中携带 `Authorization: Bearer sk-xxx` 格式的 Token。正常流程下:
- 从 `Authorization` 头提取 Bearer Token
`litellm/proxy/auth/user_api_key_auth.py`
→`_get_bearer_token_or_received_api_key()`
- 断言 Token 以 `sk-` 开头
`user_api_key_auth.py`
→`assert api_key.startswith("sk-")`
- 对 Token 做 SHA256 哈希
`user_api_key_auth.py`
→`hash_token(api_key)`
- 用哈希后的值查询数据库
`litellm/proxy/auth/auth_checks.py`
→`get_key_object(hashed_token=hash_token(api_key))`
→`_fetch_key_object_from_db_with_reconnect()`
→`prisma_client.get_data(token=hashed_token,table_name="combined_view")`
所以正常路径是安全的------因为 SHA256 哈希只产生 `0-9a-f` 字符,无法构造 SQL 注入 payload。
- 漏洞根因:错误处理回调中的 f-string 拼接
漏洞发生在认证失败的错误处理路径中,而非主认证流程。当发送的 Token 不以 `sk-` 开头时:
HTTP 请求: Authorization: Bearer <payload>
- litellm/proxy/auth/user_api_key_auth.py
→_get_bearer_token_or_received_api_key() 提取 Bearer Token
→assert api_key.startswith("sk-") 断言失败,payload 以 ' 开头
- litellm/proxy/auth/user_api_key_auth.py
→UserAPIKeyAuthExceptionHandler._handle_authentication_error(api_key=api_key) 原始 payload 作为 api_key 传入
- itellm/proxy/auth/auth_exception_handler.py
→post_call_failure_hook(user_api_key_dict=UserAPIKeyAuth(api_key=api_key)) 原始 payload 封装进 user_api_key_dict
- litellm/proxy/utils.py
→post_call_failure_hook()
→回调链 再次调用 get_key_object(hashed_token=RAW_PAYLOAD)
- litellm/proxy/auth/auth_checks.py
→get_key_object()
→_fetch_key_object_from_db_with_reconnect()
→prisma_client.get_data(token=RAW_PAYLOAD,table_name="combined_view")
- 关键步骤:litellm/proxy/utils.py
→get_data()
→hashed_token = _hash_token_if_needed(token=token)
→因 payload 不以 "sk-" 开头,直接返回原始值
- litellm/proxy/utils.py
→sql_query = f"""...WHERE v.token = '{token}'""" 原始 payload 拼入 SQL
- litellm/proxy/utils.py
→_query_first_with_cached_plan_fallback(sql_query)
→self.db.query_first(query=sql_query) 直接执行,注入完成
从 Authorization 头到 SQL 注入点的污点传播路径:

- 关键函数 `_hash_token_if_needed()`(`litellm/proxy/utils.py`)
这个函数是整个漏洞的核心开关。它的设计意图是兼容已经哈希过的 token(SHA256 hex 字符串不以 `sk-` 开头),但它同时也让攻击者构造的恶意输入畅通无阻地流入了 f-string SQL 拼接。攻击者只需确保 payload 不以 `sk-` 开头(例如以单引号 `'` 开头),即可绕过哈希处理,原样注入到 SQL 查询中。
def _hash_token_if_needed(token: str) -> str:
Hash the token if it's a string and starts with "sk-"
Else return the token as is
if token.startswith("sk-"):
return hash_token(token=token)
else:
return token # ← 非 sk- 开头的 token 原样返回,不做任何处理
漏洞复现

修复方案
核心改动是将 f-string 拼接替换为参数化查询。修复后,即使 `_hash_token_if_needed()` 对非 `sk-` 前缀的 token 原样返回,该值也不会拼入 SQL 文本,而是作为 `$1` 占位符的绑定参数,由 PostgreSQL 驱动安全处理。
产品支持
网宿全站防护-WAF已支持对该漏洞利用攻击的防护,并持续挖掘分析其他变种攻击方式和各类组件漏洞,第一时间上线防护规则,缩短防护"空窗期"。