flawopen.com/AI Security/berriai-litellm-ghsa-7hp6-salt-key-session-token-privilege-escalation
LiteLLM: escalada de privilegios por salt key (GHSA-7hp6)
LiteLLM reutilizaba el cifrado de secretos para los tokens de sesión de la interfaz y la CLI. Un internal_user autenticado podía hacer pasar datos de identidad bajo su control por esa ruta y obtener proxy_admin; ese rol podía alcanzar ejecución de comandos mediante MCP stdio. La corrección vincula los tokens a un prefijo y contexto autenticado AES-GCM. No consta un CVE ni explotación confirmada en el entorno real.[1], [2]
Un edificio usa el mismo sello para cerrar un sobre de almacenamiento y emitir una credencial de administrador. Un visitante puede influir en el contenido del sobre, y después un guardia lo confunde con una credencial auténtica. La corrección de LiteLLM da a las credenciales de sesión una etiqueta propia y la vincula criptográficamente al sello.[1], [2]
Conceptos Clave y Términos
Salt key- Material de clave configurado en LiteLLM y usado por sus funciones de cifrado. El fallo reutilizaba esa ruta sin vincular el ciphertext a su propósito.[1], [2]
Datos adicionales autenticados (AAD)- Datos, como un prefijo de tipo de token, que AES-GCM autentica junto con el ciphertext. Si cambian o faltan, la autenticación falla.[2]
internal_user y proxy_admin- Roles de LiteLLM. El aviso indica que un internal_user autenticado podía escalar a proxy_admin, el rol administrativo.[1]
MCP stdio- Transporte del Model Context Protocol que inicia un proceso local e intercambia mensajes por la entrada y salida estándar. El aviso indica que proxy_admin podía llegar a la ejecución de comandos por ese endpoint.[1]
Mapeos de marcos
- Mapeo conceptual de FlawOpen a MITRE CWE; ningún proveedor ni registro CVE asignó este identificador de debilidad a esta demostración de investigación. CWE-345
Flujo de Ataque Paso a Paso
Una cuenta con pocos privilegios llega a la gestión de claves
La condición inicial del aviso es un internal_user autenticado. No se requiere acceso anónimo, pero el actor ya debe tener ese rol.[1]
El acceso administrativo alcanza MCP stdio
Con proxy_admin, el aviso indica que el actor podía ejecutar comandos mediante el endpoint MCP stdio. Es capacidad de proceso en el host, no una orden ejecutada por el modelo.[1]
Análisis de Causa Raíz
El aviso GHSA-7hp6-4w63-5g45 de BerriAI describe un fallo de autenticación entre propósitos. LiteLLM usaba el helper de cifrado de valores tanto para secretos almacenados como para tokens de sesión de la interfaz y la CLI; la autenticación de sesión descifraba los valores mediante la misma ruta de clave. Un internal_user podía solicitar una clave cuya metadata contuviera datos de identidad serializados bajo su control; la ruta de gestión cifraba y devolvía ese valor. Al presentar el ciphertext como bearer token, la ruta de sesión podía descifrarlo e interpretar la identidad falsificada como proxy_admin, que podía acceder a la ejecución de comandos MCP stdio. La corrección upstream f7cd90f cambia la creación y validación del token: usa el prefijo litellm_login_, AAD AES-GCM ligado a ese prefijo y un decodificador específico. La salt key sigue siendo material criptográfico; la frontera demostrada es el propósito autenticado del token y su decodificador correspondiente. Por ello, el ciphertext de un valor almacenado no valida como token de sesión. El aviso asigna CVSS 3.1 9.9 Critical; las versiones posteriores a 1.91.0 están afectadas por defecto, y 1.87.0–1.90.x solo si EXPERIMENTAL_UI_LOGIN=true. Las versiones corregidas enumeradas son 1.100.4, 1.101.3, 1.102.2, 1.103.1 y 1.104.0rc2 en sus ramas respectivas. La mitigación temporal EXPERIMENTAL_UI_LOGIN=false desactiva la ruta vulnerable, pero también interrumpe CLI SSO y el inicio de sesión de Claude Code gateway. El aviso no asigna CVE ni confirma explotación real. El código muestra el cambio de dominio de autenticación upstream; no es un exploit ni una implementación completa.[1], [2], [3], [4]
Código Fuente: Vulnerable vs. Seguro
La corrección upstream sustituye el cifrador y descifrador genéricos en la creación y autenticación de sesiones. encrypt_bearer_token autentica el prefijo como AAD AES-GCM; decrypt_bearer_token exige el mismo prefijo y AAD. Así, el ciphertext de almacenamiento no puede reutilizarse como token de inicio de sesión. Es un fragmento reducido del commit citado, no código de autenticación independiente. La clave salt compartida no demuestra por sí sola que exista una clave única para cada propósito; la separación verificada aquí es el tipo de token autenticado y su descifrador correspondiente.[2], [3]
Fragmento de origen: litellm/proxy/auth/auth_checks.py y litellm/proxy/common_utils/encrypt_decrypt_utils.py — fragmentos reducidos del commit upstream f7cd90f
# Antes de la corrección: el ciphertext de valores almacenados también se emitía como token de sesión.
return encrypt_value_helper(valid_token.model_dump_json(exclude_none=True))
# La autenticación de sesión descifraba mediante el helper genérico de valores.
decrypted_token = decrypt_value_helper(hashed_token, key="ui_hash_key")
# Tras la corrección: los tokens de sesión tienen un tipo y AAD propios.
LITELLM_SESSION_TOKEN_PREFIX = "litellm_login_"
return encrypt_bearer_token(
valid_token.model_dump_json(exclude_none=True),
prefix=LITELLM_SESSION_TOKEN_PREFIX,
)
# La autenticación usa el descifrador correspondiente a esa finalidad.
decrypted_token = decrypt_bearer_token(
hashed_token, prefix=LITELLM_SESSION_TOKEN_PREFIX
)
Lista de Verificación de Seguridad para Ingeniería
- ✓Actualiza cada despliegue de LiteLLM a una versión corregida de su rama y verifica el paquete o imagen resueltos; no dependas de una etiqueta flotante.[1], [3], [4]
- ✓En 1.87.0–1.90.x, comprueba si EXPERIMENTAL_UI_LOGIN estaba habilitado; el aviso indica que solo ese caso está afectado.[1]
- ✓Si no puedes actualizar de inmediato, usa
EXPERIMENTAL_UI_LOGIN=falsecomo medida temporal y planifica la pérdida documentada de CLI SSO y del login de Claude Code gateway.[1] - ✓Añade una prueba que demuestre que el descifrador de sesión rechaza ciphertext almacenado y que acepta un token de sesión válido y no vencido.[2]
- ✓Vincula el propósito del ciphertext: autentica el prefijo como AAD AES-GCM al emitir y verificar; no aceptes la salida de un helper genérico como token de identidad.[2]
- ✓Limita la gestión de claves y la configuración de MCP stdio a los roles necesarios y ejecuta el proxy con privilegios mínimos del sistema operativo.[1]
- ✓Análisis de FlawOpen: Instrumente la auditoría de autenticación del despliegue para registrar principal, rol resuelto, tipo de token, hora e ID de solicitud, sin guardar bearer tokens ni texto cifrado; pruebe el esquema del evento. Añada una prueba de alerta para procesos del proxy LiteLLM que inicien procesos secundarios MCP stdio y correlacione los eventos de autenticación y proceso durante una investigación. Son recomendaciones de detección en el despliegue, no señales de registro confirmadas por el proveedor.
- ✓Registra el identificador GHSA-7hp6-4w63-5g45: el aviso no enumera CVE y las fuentes revisadas no confirman explotación real.[1]
Fuentes
- 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