When LLM Gateways Go Wrong: Findings from LiteLLM

Wait 5 sec.

TL;DR;Our security assessment of LiteLLM (v1.77.7), a widely used open-source LLM gateway, uncovered multiple high-impact vulnerabilities (tracked as CVE-2026-35029, CVE-2026-59823) which have been resolved as of LiteLLM version 1.83.9.The most significant issues stemmed from a missing authorization check on the /config/update endpoint, which allowed any authenticated user (including low-privileged accounts) to modify the proxy’s runtime configuration. This single flaw enabled arbitrary file read, administrative account takeover, and remote code execution via malicious Python modules loaded from cloud storage. A separate SSRF vulnerability in the “Clientside LLM Credentials” feature allowed attackers to redirect API calls and exfiltrate provider keys. These findings highlight that as AI infrastructure tools rapidly evolve, foundational security practices like proper access control and input validation remain essential.IntroductionAs LLM gateways see wider adoption, understanding the security risks they introduce is essential to deploying them safely within an AI stack. These systems sit between applications and model providers and often handle credentials, configuration, and request routing. We decided to take a closer look at LiteLLM, one of the most popular LLM gateways in use today. What started as an exploratory review uncovered multiple high severity vulnerabilities, including credential extraction, access control bypass, and remote code execution. This post presents our findings and highlights the security pitfalls that can arise in LLM gateway deployments and the wider LLM ecosystem.What are LLM Gateways?LLM gateways are systems that sit between an application and one or more LLM providers. Instead of calling model APIs directly, applications route requests through a gateway, which then forwards those requests to the appropriate model backend.In practice, LLM gateways are often used to centralize concerns such as provider abstraction, credential management, request routing, rate limiting, logging, and usage tracking. Many gateways also add higher level features like fallback logic, load balancing across providers, and configuration driven model selection.LiteLLMLiteLLM is an open-source project that provides an SDK and a gateway product for working with multiple LLM providers. The project originated through Y Combinator and is widely used across the LLM ecosystem.In this post, we focus exclusively on the LiteLLM gateway. The gateway is commonly deployed as a standalone service and plays a central role in how LLM requests are handled in many LLM-based applications. Its widespread adoption and position in the request path made it a suitable target for our research.Our review of LiteLLM was conducted against version 1.77.7. The sections below outline the defects we discovered in the LiteLLM gateway.Access Control Bypass in /config EndpointThe LiteLLM proxy exposes an administrative endpoint ‘POST /config/update’, designed to allow runtime modifications to the proxy configuration. This endpoint facilitates updating critical settings, including environment variables, model lists, and general proxy settings.The VulnerabilityThe vulnerability stems from a missing role-based access control (RBAC) check within the endpoint’s implementation, combined with an overly permissive route allowlist for UI sessions.1. Missing Function-Level AuthorizationIn secure administrative endpoints within LiteLLM (e.g., /invitation/new), the code explicitly verifies that the authenticated user possesses the PROXY_ADMIN role before proceeding.Secure Example (/invitation/new in litellm/proxy/proxy_server.py):@router.post(“/invitation/new”,tags=[“Invite Links”],dependencies=[Depends(user_api_key_auth)],response_model=InvitationModel,include_in_schema=False,)async def new_invitation(data: InvitationNew, user_api_key_dict: UserAPIKeyAuth = Depends(user_api_key_auth)):# …# Explicit Role Checkif user_api_key_dict.user_role != LitellmUserRoles.PROXY_ADMIN:raise HTTPException(status_code=400,detail={“error”: “{}, your role={}”.format(CommonProxyErrors.not_allowed_access.value,user_api_key_dict.user_role,)},)# … business logic …However, the update_config function relies entirely on the generic user_api_key_auth dependency without performing a subsequent role check on the returned user object.Vulnerable Code (/config/update in litellm/proxy/proxy_server.py):@router.post(“/config/update”,dependencies=[Depends(user_api_key_auth)], # Only generic auth checkinclude_in_schema=False,)async def update_config(config_info: ConfigYAML):# …# MISSING: if user_role != PROXY_ADMIN: raise …# …# Proceed to update configurationawait proxy_config.save_config(new_config=config)2. Route Allowlist Bypass via UI Token ClassificationThe user_api_key_auth dependency delegates authorization to a common_checks function. This function determines if a request is allowed based on the user’s role and the target route.Step 2.a: UI Login Creates Token with litellm-dashboard TeamWhen any user logs into the LiteLLM UI, the backend generates a temporary API key explicitly associated with the special litellm-dashboard team. This occurs in multiple login flows:# litellm/proxy/proxy_server.py (login flows at lines ~7962, ~8066, ~8203)response = await generate_key_helper_fn(request_type=”key”,**{“user_role”: user_role,“duration”: “24hr”,“key_max_budget”: litellm.max_ui_session_budget,“models”: [],“aliases”: {},“config”: {},“spend”: 0,“user_id”: user_id,“team_id”: “litellm-dashboard”, # bool:if token_type == “ui” and _is_ui_route(route=route, user_obj=user_obj):return True #