Introduction
LiteLLM has become the de facto open-source proxy for organizations routing requests to multiple large language model providers — OpenAI, Anthropic, Azure OpenAI, Bedrock, and dozens more — through a single unified API. It sits at the center of your AI stack, which means it holds the crown jewels: provider API keys, cloud credentials, and a direct network path into your internal environment.
New research from Wiz ("Off Guard: Breaking LiteLLM from authentication bypass to cloud compromise") demonstrates a full compromise chain against LiteLLM deployments: starting from default or predictable master keys, moving through unauthenticated MCP (Model Context Protocol) sessions, and culminating in arbitrary code execution via custom code guardrails — ultimately yielding root-level access on the gateway host and theft of cloud IAM credentials attached to the underlying compute identity.
This is not a theoretical attack. LiteLLM gateways are routinely deployed with broad IAM roles (to reach Bedrock, Vertex AI, or Azure OpenAI), run in containers with host network access, and are frequently exposed to the internet or to large internal user populations. If your organization operates a LiteLLM proxy — self-hosted, in Kubernetes, or on a VM — assume it is a high-value target and treat the findings below as an immediate action plan.
Technical Analysis
Affected Component
- Product: LiteLLM Proxy Server (open-source LLM gateway), self-hosted deployments (Docker, Kubernetes, VM-based)
- Platforms: Any environment where the LiteLLM proxy handles requests to downstream LLM providers and executes user-controllable guardrail code
- Note: The Wiz research describes a chain of misconfiguration-driven weaknesses and architectural trust failures rather than a single CVE. The defensive lesson applies to any LiteLLM version deployed with default credentials, exposed MCP endpoints, and permissive guardrail configuration.
Attack Chain Breakdown
The Wiz team chained three distinct weaknesses into full cloud compromise. Understanding each stage is essential for building layered detection.
Stage 1 — Authentication Bypass via Default or Weak Master Keys.
LiteLLM proxies are frequently deployed with the master key left at a default value (the classic sk-1234 placeholder from documentation and quick-start guides) or with weak, guessable keys. Possession of the master key grants full administrative control of the proxy: creating virtual keys, modifying model configurations, reading logs that may contain request payloads, and — critically — configuring guardrails.
Defender's view: any LiteLLM instance accepting a default master key is effectively unauthenticated. Because LiteLLM proxies are spun up quickly by developers and data science teams (often outside IT change control), shadow deployments with default keys are common.
Stage 2 — Unauthenticated MCP Sessions. LiteLLM exposes Model Context Protocol (MCP) server functionality to let agents invoke tools. Wiz found that MCP sessions could be established without proper authentication, allowing an attacker to interact with tool integrations and internal endpoints through the gateway. MCP servers bridge LLM agents to real capabilities — file systems, APIs, databases — so an unauthenticated MCP channel is a direct path into whatever the gateway can reach.
Defender's view: MCP endpoints (/mcp, SSE-based transport endpoints) must be treated like any other admin API. Unauthenticated MCP traffic, especially sessions spawning tool invocations, is a high-fidelity anomaly.
Stage 3 — Code Execution via Custom Code Guardrails. LiteLLM supports custom guardrails implemented as user-supplied Python code, executed server-side to inspect or transform requests and responses. With administrative access (obtained in Stage 1) or via an exposed configuration path, an attacker can register a malicious guardrail — arbitrary Python executed in the LiteLLM process context, typically as root inside a container.
Defender's view: this is the payload stage. The LiteLLM Python process spawning shells, writing files to unusual locations, or establishing outbound connections is the single highest-fidelity detection opportunity in the chain.
Stage 4 — Cloud IAM Credential Theft. From code execution on the gateway, the attacker harvests cloud credentials: the EC2 instance metadata service (IMDS) on AWS, the GCE metadata server on GCP, or managed identity endpoints on Azure. Because LiteLLM gateways commonly carry roles permitting Bedrock/SageMaker/Vertex invocation — and are often over-privileged — stolen session credentials translate directly into cloud control-plane access.
Exploitation Status
The research demonstrates a complete, reproducible exploit chain against realistic deployment patterns. While this disclosure is framed as research rather than a confirmed mass-exploitation campaign, the prerequisites (default keys, internet exposure) are trivially discoverable via internet scanning, and LiteLLM's popularity in production AI pipelines makes opportunistic exploitation highly likely. Treat as actively exploitable in the wild for any internet-reachable instance.
Detection & Response
The detection strategy below targets the most observable stages: administrative abuse of the proxy, anomalous process behavior from the LiteLLM runtime, metadata-service credential theft, and the presence of default-key configurations.
Sigma Rules
---
title: LiteLLM Python Process Spawning Shell or Command Interpreter
id: 8c1f2a4d-6b3e-4f5a-9c7d-2e1b8a0f4d6c
status: experimental
description: Detects the LiteLLM proxy Python process spawning a shell or scripting interpreter, consistent with code execution via malicious custom guardrails as described in Wiz 'Off Guard' research.
references:
- https://www.wiz.io/blog/off-guard-breaking-litellm-from-authentication-bypass-to-cloud-compromise
- https://attack.mitre.org/techniques/T1059/
author: Security Arsenal
date: 2026/04/06
tags:
- attack.execution
- attack.t1059.006
logsource:
category: process_creation
product: linux
detection:
selection_parent:
ParentCommandLine|contains:
- 'litellm'
- 'uvicorn'
- 'gunicorn'
selection_child:
Image|endswith:
- '/sh'
- '/bash'
- '/dash'
- '/python'
- '/python3'
- '/curl'
- '/wget'
- '/nc'
- '/ncat'
condition: selection_parent and selection_child
falsepositives:
- Legitimate LiteLLM integrations invoking subprocesses for tool execution — baseline per deployment
level: high
---
title: Cloud Instance Metadata Service Access from Application Process
id: 2d7e9b1c-4a5f-4c8d-b6e3-1f0a9c2d5e7b
status: experimental
description: Detects non-system processes (including Python/uWSGI workers running LiteLLM) querying the cloud instance metadata service, a strong indicator of IAM credential theft following gateway compromise.
references:
- https://www.wiz.io/blog/off-guard-breaking-litellm-from-authentication-bypass-to-cloud-compromise
- https://attack.mitre.org/techniques/T1552/005/
author: Security Arsenal
date: 2026/04/06
tags:
- attack.credential_access
- attack.t1552.005
logsource:
category: network_connection
product: linux
detection:
selection_ip:
DestinationIp:
- '169.254.169.254'
- 'fd00:ec2::254'
selection_proc:
Image|endswith:
- '/python'
- '/python3'
- '/curl'
- '/wget'
condition: selection_ip and selection_proc
falsepositives:
- Legitimate SDK calls from the gateway itself (boto3/azure identity) — investigate token endpoint path and frequency; IMDSv2 enforcement reduces risk
level: high
---
title: LiteLLM Proxy Access with Default Master Key Pattern
id: 5a3c8f2e-7d1b-4e6a-a9f4-3b8d1c6e0a2f
status: experimental
description: Detects proxy/web logs showing requests to LiteLLM administrative or virtual-key management endpoints, which should be tightly restricted and are a key target after authentication bypass via default master keys.
references:
- https://www.wiz.io/blog/off-guard-breaking-litellm-from-authentication-bypass-to-cloud-compromise
- https://attack.mitre.org/techniques/T1078/
author: Security Arsenal
date: 2026/04/06
tags:
- attack.initial_access
- attack.t1078
logsource:
category: webserver
detection:
selection:
cs-uri-stem|contains:
- '/key/generate'
- '/key/update'
- '/key/delete'
- '/user/new'
- '/config/update'
- '/guardrail'
- '/mcp'
filter_internal:
c-ip|startswith:
- '10.'
- '192.168.'
condition: selection and not filter_internal
falsepositives:
- Legitimate administrative API calls from external admin tooling — restrict admin endpoints to internal networks or mTLS
level: medium
KQL — Microsoft Sentinel / Defender
The following hunt query targets anomalous behavior from LiteLLM workloads ingested via Syslog/CEF or Defender for Endpoint (for container hosts with MDE onboarded), plus metadata-service access attempts. Tune the process list to your actual LiteLLM runtime (container image name, entrypoint).
// Hunt: LiteLLM gateway process spawning shells, network tools, or reaching cloud metadata service
let litellm_procs = dynamic(["python", "python3", "uvicorn", "gunicorn", "litellm"]);
let suspicious_children = dynamic(["sh", "bash", "dash", "curl", "wget", "nc", "ncat", "socat", "chisel"]);
union isfuzzy=true
(DeviceProcessEvents
| where InitiatingProcessFileName in~ (litellm_procs)
| where FileName in~ (suspicious_children)
| project TimeGenerated, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, FileName, ProcessCommandLine, AccountName, Source="MDE"),
(Syslog
| where ProcessName in~ (suspicious_children)
| where SyslogMessage has_any ("litellm", "uvicorn") or Computer has "litellm"
| project TimeGenerated, Computer, ProcessName, SyslogMessage, Source="Syslog"),
(CommonSecurityLog
| where DestinationIP == "169.254.169.254"
| where ApplicationProtocol =~ "HTTP" or isnotempty(RequestURL)
| project TimeGenerated, SourceIP, DestinationIP, RequestURL, SourceProcessName, Source="CEF")
| order by TimeGenerated desc
// Hunt: External hits to LiteLLM admin/MCP endpoints via WAF or reverse-proxy logs (ingest as Custom Log or via CEF)
CommonSecurityLog
| where RequestURL has_any ("/key/generate", "/key/update", "/config/update", "/guardrail", "/mcp", "/user/new")
| where SourceIP !startswith "10." and SourceIP !startswith "192.168." and SourceIP !startswith "172.16."
| summarize FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated), Hits=count(), Endpoints=dcount(RequestURL) by SourceIP, RequestURL, DeviceAction
| order by Hits desc
Velociraptor VQL
Use this artifact across Linux gateway hosts and container nodes to surface LiteLLM processes with anomalous children, active connections to the metadata service, and recently modified guardrail configuration files.
-- Hunt: LiteLLM gateway compromise indicators — child processes, metadata connections, guardrail artifacts
SELECT Pid, Ppid, Name, CommandLine, Exe, Username, CreateTime
FROM pslist()
WHERE (CommandLine =~ '(?i)litellm|uvicorn|gunicorn')
OR (Exe =~ '(?i)python' AND CommandLine =~ '(?i)proxy|litellm')
-- Correlate: any shell or network tool whose parent is a Python/uvicorn process
SELECT Pid, Ppid, Name, CommandLine, Username, CreateTime
FROM pslist()
WHERE Name =~ '(?i)^(sh|bash|dash|curl|wget|nc|ncat|socat)$'
AND Ppid IN (SELECT Pid FROM pslist() WHERE Exe =~ '(?i)python' OR CommandLine =~ '(?i)uvicorn|gunicorn|litellm')
-- Network: established connections to cloud metadata service
SELECT Pid, Name, LocalAddr, LocalPort, RemoteAddr, RemotePort, Status
FROM netstat()
WHERE RemoteAddr =~ '169\\.254\\.169\\.254'
-- Filesystem: recently modified LiteLLM config and guardrail code
SELECT FullPath, Size, Mtime, Ctime
FROM glob(globs=['/etc/litellm/**', '/app/**/config.yaml', '/app/**/custom_guardrail*', '/app/**/guardrails/**', '/root/.config/litellm/**'])
WHERE Mtime > now() - 86400 * 3
Remediation & Verification Script
Run on LiteLLM gateway hosts and Kubernetes nodes to audit for default keys, exposed admin surface, and metadata-service exposure, and to apply baseline hardening.
#!/bin/bash
# Security Arsenal — LiteLLM Gateway Hardening & Compromise Audit
# Usage: sudo ./litellm_hardening_audit.sh
set -euo pipefail
echo "=== [1] Locate LiteLLM configuration files ==="
CONFIG_PATHS=$(find /etc /app /opt /home /root -maxdepth 5 \( -name 'config.yaml' -o -name '.env' -o -name 'litellm*config*' \) 2>/dev/null | xargs grep -l -i 'litellm\|master_key' 2>/dev/null || true)
echo "$CONFIG_PATHS"
echo "=== [2] Check for default / weak master keys ==="
for f in $CONFIG_PATHS; do
if grep -Ei 'master_key.*(sk-1234|changeme|default|password|test)' "$f" >/dev/null 2>&1; then
echo "[CRITICAL] Default or weak master key in: $f"
fi
done
echo "=== [3] Environment variable exposure ==="
env | grep -i 'LITELLM_MASTER_KEY\|GENERAL_SETTINGS' | sed 's/=.*/=<redacted>/' || echo "No LiteLLM env vars set at shell level (check container runtime)"
echo "=== [4] Audit LiteLLM process tree for anomalous children ==="
for pid in $(pgrep -f 'litellm|uvicorn|gunicorn' 2>/dev/null || true); do
echo "-- PID $pid: $(tr '\0' ' ' < /proc/$pid/cmdline 2>/dev/null)"
ps --ppid "$pid" -o pid,comm,args 2>/dev/null || true
done
echo "=== [5] Check metadata service reachability (should fail from gateway pods) ==="
if curl -s --max-time 2 -H 'Metadata-Flavor: Google' http://169.254.169.254/ >/dev/null 2>&1 || \
curl -s --max-time 2 http://169.254.169.254/latest/meta-data/ >/dev/null 2>&1; then
echo "[WARNING] Cloud metadata service is reachable from this host — enforce IMDSv2/hop-limit or block at network layer"
else
echo "[OK] Metadata service not directly reachable"
fi
echo "=== [6] Verify LiteLLM version ==="
python3 -c 'import litellm; print("litellm", litellm.__version__)' 2>/dev/null || pip3 show litellm 2>/dev/null | head -2 || echo "Not installed via pip on host (check container image tag)"
echo "=== [7] Kubernetes: check for network policies restricting the litellm namespace ==="
if command -v kubectl >/dev/null 2>&1; then
kubectl get networkpolicies -A 2>/dev/null | grep -i litellm || echo "[WARNING] No NetworkPolicy found for LiteLLM namespace"
kubectl get pods -A -o wide 2>/dev/null | grep -i litellm || true
fi
echo "=== Audit complete. Review [CRITICAL] and [WARNING] items immediately. ==="
Remediation
Prioritize these actions in order. Items 1–3 are same-day; the remainder within the week.
-
Rotate every LiteLLM master key and virtual key immediately. Remove any instance of the default
sk-1234or other placeholder keys from configuration files, environment variables, and container images. Use long, randomly generated keys stored in a secrets manager (AWS Secrets Manager, HashiCorp Vault, Azure Key Vault) — never in committed config files. -
Inventory and reduce exposure of the proxy. Locate all LiteLLM deployments, including shadow instances run by developer/data teams. Remove internet exposure; place the gateway behind an authenticated reverse proxy or API gateway with its own authN/authZ layer. Restrict administrative endpoints (
/key/*,/config/*,/user/*,/guardrail*) to internal networks or mTLS only. -
Audit guardrails and MCP configuration. Review all registered custom guardrails for unauthorized code. Disable custom code guardrail execution entirely if your use case does not require it, or sandbox execution (seccomp, gVisor, or a dedicated isolated worker with no cloud credentials). Require authentication on all MCP endpoints and log every session establishment and tool invocation.
-
Constrain cloud credentials on gateway workloads. Enforce IMDSv2 with a hop limit of 1 on AWS so containers cannot reach instance credentials; scope the gateway's IAM role to the minimum LLM-invoke permissions required; on Kubernetes use IRSA (EKS) / Workload Identity (GKE/AKS) rather than node roles. Consider blocking 169.254.169.254 egress from the LiteLLM namespace via NetworkPolicy.
-
Update to the latest LiteLLM release. Track the project's GitHub security advisories and Wiz's disclosure (https://www.wiz.io/blog/off-guard-breaking-litellm-from-authentication-bypass-to-cloud-compromise) for version-specific fixes related to MCP authentication and guardrail handling. Pin and rebuild container images; do not run mutable tags in production.
-
Hunt retroactively. Run the detection content above against the last 90 days of proxy, process, and network telemetry. Look specifically for: virtual keys you did not create, unexpected guardrail entries, outbound connections from the gateway to unfamiliar hosts, and any cloud API calls from the gateway role outside normal LLM-invoke patterns.
-
Add LiteLLM to your attack surface management and pen-test scope. AI gateways are now first-class infrastructure. They belong in your external scanning inventory, your penetration test scope, and your threat model.
Closing Perspective
This research is a template for a class of attacks we will see repeatedly in 2026: AI infrastructure deployed fast, configured from quick-start documentation, holding powerful cloud credentials, and trusted implicitly by downstream systems. The defensive fundamentals are not new — no default credentials, no unauthenticated admin surfaces, no arbitrary code execution paths reachable by lower-privileged users, least-privilege cloud identity — but they must now be applied to LLM gateways, MCP servers, and agent toolchains with the same rigor we apply to VPN concentrators and CI/CD servers. If your LiteLLM gateway fell tomorrow, the blast radius should be a revoked API key, not your cloud account.
Related Resources
Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.