Een standaard account met weinig rechten op een LiteLLM-proxy kan naar volledige beheerdersrechten klimmen en code op de server uitvoeren door drie kwetsbaarheden aan elkaar te koppelen, zo onthulden onderzoekers van Obsidian Security
LiteLLM is een wijdverspreide open-source AI-gateway die oproepen naar meer dan 100 modelaanbieders bemiddelt achter één OpenAI-compatibele interface.
Bij een serverovername worden elke providersleutel die deze bevat, de geheimen die de opgeslagen inloggegevens ontsleutelen, en elke prompt en reactie die er doorheen gaat, blootgelegd.
Obsidian beoordeelt de volledige CVSS-keten met 9,9 in het kritieke bereik. BerriAIde beheerder, heeft de volledige fixset opgenomen in LiteLLM v1.83.14-stable, die door GitHub wordt vermeld als vrijgegeven op 2 mei. Upgrade naar die release of later om de keten met drie CVE’s te sluiten.
De drie fouten
De eerste link is CVE-2026-47101, een autorisatie-bypass. Wanneer een gewone gebruiker (een internal_user) een virtuele API-sleutel genereert, slaat LiteLLM het door de beller aangeleverde veld allow_routes op zonder dit te vergelijken met de rol van de gebruiker.
Het veld wordt verondersteld te beperken wat een sleutel kan doen. In plaats daarvan behandelt de proxy het ook als een reservetoekenning, zodat een niet-beheerder een sleutel kan maken met allow_routes: (“/*”), een jokerteken dat elke route bereikt, inclusief alleen de beheerdersroutes. Dezelfde ongecontroleerde schrijfwijze verschijnt op de andere eindpunten voor sleutelbeheer. Daarom waren er drie pull-aanvragen nodig om de oplossing te bereiken.
Als de routepoort wordt omzeild, worden de handlers erachter bereikbaar. Een aantal van hen gaat ervan uit dat de poort de screening al heeft gedaan, waardoor er twee paden opengaan.
Een daarvan is CVE-2026-47102, escalatie van bevoegdheden. Met het /user/update-eindpunt kan een gebruiker zijn eigen record bewerken, maar wordt niet beperkt welke velden hij kan schrijven. Een zelfupdate met user_role: “proxy_admin” wordt geaccepteerd en opgeslagen, waardoor de beller wordt gepromoveerd tot volledige proxybeheerder. Een org_admin kan dit eindpunt bereiken via een legitiem, bedoeld codepad zonder dat er omzeiling nodig is; een standaard internal_user bereikt het na CVE-2026-47101.
VulnCheck, die de CVE heeft toegekend, scoort een 8,7 onder CVSS 4.0, een 8,8 onder 3,1.
De andere is CVE-2026-40217, een sandbox-escape in de Custom Code Guardrail, die door de beheerder geleverde Python compileert en uitvoert. De productie-eindpunten voerden de code uit via exec() zonder filtering op bronniveau. Wanneer exec() een globaal dictaat krijgt zonder __builtins__, injecteert Python stilletjes de volledige ingebouwde module, die de code __import__, open en eval overhandigt. Een eenvoudige payload die os.system aanroept, was toen voldoende voor een omgekeerde shell.
Een apart pad op het /guardrails/test_custom_code speelveldeindpunt, onafhankelijk gevonden door X41 D-Sec, versloeg een regex-weigerlijst door het herschrijven van runtime bytecodes. Beide eindigden in het uitvoeren van code op de server.
Wat een aanvaller krijgt
LiteLLM zit op een knelpunt, dus het bereik is groot. Een volledige keten onthult de hoofdsleutel, de salt-sleutel die opgeslagen inloggegevens ontsleutelt, en de database-URL. Het onthult ook elke geconfigureerde providersleutel, voor OpenAI, Anthropic, Gemini, Bedrock, Azure en de rest.
Sleutels in configuratie of omgeving zijn platte tekst; sleutels in de database zijn gecodeerd maar kunnen worden hersteld met de salt-sleutel. Alles dat via de gateway wordt verzonden, prompts en antwoorden, wordt leesbaar, en in echte implementaties komen PII, broncode, interne tickets en geplakte geheimen terecht.

Als de proxy ook als Model Context Protocol (MCP) of agentgateway draait, vallen OAuth-tokens en toolreferenties ook binnen het bereik.
Het scherpere risico is niet wat een aanvaller leest, maar wat hij kan herschrijven. De gateway bevindt zich op de draad tussen een AI-agent en het model, dus door een compromis kan de respons tijdens de overdracht worden gewijzigd.
Obsidian demonstreerde dit tegen Claude Code, gerouteerd via een gecompromitteerde proxy. Dit is geen snelle injectie. In plaats van het model over te halen zich te misdragen, gebruikt de aanvaller het ingebouwde callback-mechanisme van LiteLLM, een extensiepunt dat bij elk verzoek wordt geactiveerd en nooit in de beheerdersinterface verschijnt. De callback verwisselt de reactie van het model voor een vervalste tooloproep en herschrijft de context van de veiligheidscontrole, zodat de actie als goedgekeurd wordt gelezen.
In de demo typt de ontwikkelaar één woord, hallo, en de aanvaller plaatst een omgekeerde shell op de machine van de ontwikkelaar.
Los van de keten geeft LiteLLM een proxy_admin een opzettelijk code-uitvoeringspad: dankzij de MCP-ondersteuning kan een beheerder stdio MCP-servers registreren die de proxy lanceert als lokale subprocessen. Dat is eerder een ontwerpafweging dan een bug, en de patches veranderen daar niets aan, dus het bereiken van de beheerder betekent in feite het uitvoeren van code.
Obsidian heeft op deze manier een omgekeerde shell gereproduceerd in v1.88.0. Een echte bug in dezelfde stdio-MCP-machine, CVE-2026-42271, zorgde ervoor dat bellers subprocessen konden spawnen via de MCP-preview-eindpunten van LiteLLM; het werd in het wild uitgebuit en eerder deze maand toegevoegd aan de KEV-catalogus van CISA.
Niets van dit alles is LiteLLM’s eerste moeilijke traject dit jaar. In maart zorgde een compromis in de toeleveringsketen ervoor dat twee LiteLLM-releases op PyPI achter de deur werden gehouden, en in april werd binnen 36 uur na de openbaarmaking gebruik gemaakt van een cruciale SQL-injectie.
Obsidian beschrijft de keten hier als een onthulde fout met een werkende demo, niet als uitbuiting in het wild, maar de positie van de proxy maakt er steeds een doelwit van.
Wat te doen
Upgrade naar v1.83.14-stable of hoger, de eerste release met de volledige fixset. Vervolgens auditeren. Verifieer elk account met proxy_admin opnieuw en behandel die rol als toegang op hostniveau. Controleer elke Custom Code Guardrail op de proxy.
Controleer de callbacks die vanuit config.yaml zijn geladen onder litellm_settings.callbacks, aangezien deze nooit in de console verschijnen en precies daar zijn waar een post-RCE-aanvaller zich zou verstoppen. Controleer de integriteit van de geïmplementeerde code, niet alleen de configuratie. Als blootstelling wordt vermoed, roteer dan de providersleutels, databasereferenties en eventuele opgeslagen MCP-tokens.
Een gecompromitteerde proxy lekt niet alleen gegevens. Het bevindt zich tussen de agent en het model en kan de reacties smeden waarop de agent reageert. De keten die een aanvaller daarheen brengt, is op elke laag misplaatst vertrouwen: de routepoort vertrouwde het door de beller aangeleverde veld, de afhandelaars vertrouwden de routepoort en niemand controleerde het daadwerkelijk.