This is the receptionist’s desk drawer being unlockable from the parking lot
CVE-2026-42208 is a pre-auth SQL injection in LiteLLM proxy API key verification. Affected versions are >=1.81.16 and <1.83.7; the vulnerable path sits in the proxy’s auth check, where a caller-controlled Authorization header is mixed into a database query instead of parameterized, letting an unauthenticated remote client reach the database through normal LLM routes like /chat/completions.
Vendor severity is directionally right in practice, even though the published scoring is messy: the GitHub CNA advisory shows Critical 9.3, while NVD enrichment shows Critical 9.8 as of 2026-05-08. The real-world risk is not abstract SQLi math; it is that LiteLLM is a credential concentrator for OpenAI, Anthropic, Bedrock, Azure OpenAI, and other upstream keys, and this bug hits that credential broker *before* auth with confirmed exploitation and KEV listing.
4 steps from start to impact.
Reach the LiteLLM proxy
4000. LiteLLM docs show the quick-start proxy binding to http://0.0.0.0:4000, which makes accidental internet exposure plausible in test and rushed production deployments.- A LiteLLM proxy deployment exists
- The instance is running a vulnerable version
>=1.81.16,<1.83.7 - The attacker can reach the proxy over the network
- This is not the whole Python package; it is the proxy deployment path
- Many enterprises keep internal AI gateways behind VPN, mesh, or API gateway controls
- If the service is not reachable from untrusted networks, the pre-auth nature matters less
4000, but product fingerprinting is imperfect.Inject via the Authorization header
Authorization: Bearer ... header is sent to an LLM API route such as POST /chat/completions. Per the GHSA, the proxy’s key-verification query concatenates that header value into SQL instead of using a parameterized statement, so the injection lands before authentication is decided.- Any reachable LLM API route on the proxy
- No valid account or API key required
- The vulnerable path can be removed by the vendor workaround
general_settings.disable_error_logs: true - Reverse proxies, WAFs, or header normalization can break crude payloads
- Some deployments terminate access behind allowlists or private ingress
Authorization headers containing quotes, UNION, comment markers, or unusually long bearer values; generic WAF SQLi signatures may catch noisy payloads but not polished ones.Enumerate schema and high-value tables
UNION SELECT payloads or a tuned toolchain rather than blind spray-and-pray sqlmap. Sysdig observed deliberate schema enumeration against LiteLLM-specific tables holding virtual API keys, stored provider credentials, and configuration data.- Successful SQL syntax shaping against the backend database
- Knowledge of PostgreSQL/LiteLLM schema conventions or willingness to enumerate
- Column counts and identifier casing can slow generic automation
- Database permissions may limit writes even if reads succeed
- WAFs or rate controls can disrupt repeated enumeration attempts
UNION probes, or bursts of 4xx/5xx around /chat/completions.Steal or alter gateway secrets
- Readable secrets exist in the LiteLLM database or config-backed tables
- Exfiltrated keys remain valid
- Short-lived or rotated provider credentials reduce dwell time
- Perimeter egress monitoring and provider-side anomaly detection may surface misuse
- Key scoping and budget caps can limit blast radius if properly configured
general_settings.disable_error_logs: true exactly as the GHSA workaround states. Do this immediately, within hours, because KEV/active exploitation overrides the normal SLA and this removes the unauthenticated input path called out by the vendor.UNION, SQL comment markers, and abnormal bearer-token length in Authorization headers to LiteLLM routes. Deploy within 3 days at the latest on monitored edges, but faster is better because exploitation has already been seen.- MFA on the admin UI does not stop this path; the injection lands before LiteLLM authentication is decided.
- Relying on package managers alone does not help if you ship pinned containers or vendored images and never redeploy them.
- A generic network firewall without Layer-7 restrictions does not help if the proxy remains reachable on its normal API port from untrusted sources.
- Secret masking in logs does not fix the vulnerable query; it only changes what happens after the attack input has already reached the database layer.
The supporting signals.
| In-the-wild status | Confirmed exploitation signal. CISA KEV includes the CVE, and Sysdig reported targeted exploitation 36 hours after global advisory indexing. |
|---|---|
| KEV status | YES. NVD reflects CISA KEV addition on 2026-05-08 with a federal due date of 2026-05-11 and required action to apply vendor mitigations or discontinue use if unavailable. |
| PoC / weaponization | Weaponization is trivial even without a polished public PoC. The exploit primitive is a crafted bearer token on a normal API route; Sysdig observed manual UNION SELECT payloads rather than commodity sqlmap spray. |
| EPSS | 0.54262 from the user-supplied intel. That is already a very high exploitation-likelihood signal *before* you factor in KEV and observed exploitation. |
| CVSS and score divergence | There is a scoring mismatch: the GitHub CNA advisory shows Critical 9.3 (CVSS v4), while NVD shows Critical 9.8 (CVSS v3.1) as of 2026-05-08. Either way, the bucket stays critical. |
| Affected versions | litellm proxy deployments on >=1.81.16,<1.83.7 are affected per GHSA and NVD. |
| Fixed versions | Upgrade to 1.83.7 or later. The 1.83.7-stable" target="_blank" rel="noopener">release tag references the fix use parameterized query for combined_view token lookup; I found no authoritative distro backport metadata. |
| Exposure / scan reality | I did not find a trustworthy primary-source internet census count for exposed LiteLLM nodes. What *is* authoritative is the LiteLLM docs showing quick-start proxy exposure on 0.0.0.0:4000, which is enough to make accidental edge exposure realistic. |
| Disclosure timeline | GHSA was published on 2026-04-20; Sysdig says global GitHub Advisory Database indexing happened on 2026-04-24 16:17 UTC; NVD published on 2026-05-08; CISA KEV added it on 2026-05-08. |
| Researcher / reporting | The vendor advisory credits Tencent YunDing Security Lab for discovery. Follow-on exploitation research was published by Michael Clark / Sysdig Threat Research. |
Sources.
Why this verdict
- Pre-auth remote path: no credentials, no user click, normal API route, and the vulnerable code runs in the auth-check itself.
- Blast radius is credential-centric: LiteLLM is an AI gateway that stores or brokers upstream provider secrets, so a database read is effectively a pivot into paid model accounts and downstream tenant activity.
- Active exploitation and KEV erase wishful thinking: once CISA KEV and observed exploitation are on the board, this stops being theoretical patch debt and becomes an attacker-validated path.
- Only modest downward friction: the bug requires a LiteLLM proxy deployment on a narrow version band and meaningful network reachability, which trims exposed population but does not make the instances that *are* exposed any safer.
Why not higher?
There is real friction in the reachable population: this is a specific open-source AI gateway, not a mass-enterprise platform, and many deployments are internal-only. Also, successful monetization still depends on useful secrets being present and valid, not just on proving SQLi.
Why not lower?
Dropping this to HIGH or below would ignore two practitioner-grade facts: it is pre-auth over the network and it is already KEV-listed / exploited. When the vulnerable component is the place where you centralize OpenAI, Anthropic, Bedrock, and other keys, the impact is much closer to secret-store compromise than to a routine web-app SQLi.
Crowdsourced verification payload.
Run this on the target host or container image that actually serves the LiteLLM proxy, not from an auditor workstation. Invoke it as python3 check_cve_2026_42208.py /path/to/config.yaml; it needs read access to the Python environment where litellm is installed and optional read access to the LiteLLM config file. No root is required unless your config path is protected.
#!/usr/bin/env python3
# Check LiteLLM for CVE-2026-42208
# Usage: python3 check_cve_2026_42208.py /etc/litellm/config.yaml
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
import os
import re
import sys
try:
from importlib import metadata
except Exception:
print('UNKNOWN')
sys.exit(2)
def parse_version(v):
nums = [int(x) for x in re.findall(r'\d+', v)]
while len(nums) < 3:
nums.append(0)
return tuple(nums[:3])
def version_in_range(v, lower, upper):
return parse_version(lower) <= parse_version(v) < parse_version(upper)
def config_has_workaround(path):
if not path:
return False
if not os.path.exists(path):
return False
try:
text = open(path, 'r', encoding='utf-8', errors='ignore').read()
except Exception:
return False
# Cheap stdlib-only check. We do not require PyYAML.
# Accepts forms like:
# general_settings:
# disable_error_logs: true
general_block = re.search(r'general_settings\s*:(.*?)(?:\n\S|\Z)', text, flags=re.S)
if general_block and re.search(r'disable_error_logs\s*:\s*true\b', general_block.group(1), flags=re.I):
return True
# Fallback if file is flattened or templated.
if re.search(r'disable_error_logs\s*:\s*true\b', text, flags=re.I):
return True
return False
def main():
cfg = sys.argv[1] if len(sys.argv) > 1 else os.environ.get('LITELLM_CONFIG')
try:
version = metadata.version('litellm')
except metadata.PackageNotFoundError:
print('UNKNOWN')
sys.exit(2)
except Exception:
print('UNKNOWN')
sys.exit(2)
if version_in_range(version, '1.81.16', '1.83.7'):
if config_has_workaround(cfg):
# Vulnerable package present, but vendor workaround appears enabled.
# Treat as UNKNOWN because this is mitigated, not patched.
print('UNKNOWN')
sys.exit(2)
print('VULNERABLE')
sys.exit(1)
# Outside the affected range for this CVE.
print('PATCHED')
sys.exit(0)
if __name__ == '__main__':
main()