黒い基板上の抵抗器とコンデンサの接写
設計と運用

LiteLLM 1.107.0バックドア事件に学ぶpip依存管理の落とし穴

目次を見る

LLM(大規模言語モデル)を複数のプロバイダーに振り分けて呼び出すライブラリ「LiteLLM」を、CI/CDパイプラインやプロキシサーバーで使っているチームに向けた内容です。2025年10月21日、PyPI(Python Package Indexの略で、pipコマンドが参照する公式パッケージ配布サイト)に公開されたLiteLLM 1.107.0に、資格情報窃取とリモートコード実行の仕掛けが混入していたことが報告されました。依存ライブラリの自動更新を許している環境がどれだけ危険にさらされうるか、具体的に確認していきます。

何が起きたか

セキュリティ調査会社SafeDepの分析によると、該当バージョンの7種類のwheel(ビルド済みパッケージ形式)すべてに、site-packages(Pythonの依存ライブラリが格納されるディレクトリ)へ不正コードを仕込む仕組みが含まれていました。

厄介なのは、この仕掛けがlitellmをimportしなくても動く点です。SSHキー、~/.aws以下のクラウド認証情報、Azureやgcloudの設定、kubeconfig、ブラウザのパスワードと履歴、シェル履歴、CI/CDのシークレット、Claude CodeやCursorなどAIツールの設定ファイル、さらには/proc/<pid>/environ経由で他プロセスの環境変数まで収集対象だったとされています。

収集したデータは暗号化され、なりすましドメインへPOST送信されていました。加えてsitecustomize.pyとして仕込まれた2段目のペイロードが、検知を逃れるデーモンを起動し、1時間おきに再実行してGitHub上のファイルから読み取ったアドレスから新しいコードをダウンロードしてexec()する仕組みも確認されています。

LiteLLMはLLMプロバイダーへのAPIキーをプロキシのデータベースで管理する用途でも使われるため、攻撃者にとって狙い目の資格情報が集まる場所でもありました。

なぜ起きたか

原因を段階的に分解します。まず仕込まれた経緯です。SafeDepの調査では、ソース配布物(sdist)のpyproject.tomlにmaturinのdata = "cook"という設定が1行追加されていたことが突き止められています。

この設定は、本来は存在しないはずのcook/フォルダをwheelのpurelib(サードパーティライブラリの格納先)ルート、つまりsite-packages直下にコピーするものです。このフォルダは公開されているsdistにもGitHubの公開コミット履歴にも存在せず、ビルドパイプライン内部で混入したと見られています。

次に、なぜ「importしなくても実行される」のかという技術的な仕組みです。Pythonのインタプリタは起動時、site-packages内にある.pthファイルの中でimportから始まる行を自動的に実行します。加えてsitecustomizeモジュールが存在すれば、それも起動時に読み込みます。

これはPythonの公式に文書化された機能であり、脆弱性でも裏技でもありません。たとえばvenv環境でsite-packagesにcook.pthというファイルを置き、中身をimport cookの1行だけにしておくと、python -c "pass"のように何もimportしないコードを実行しただけでcook.pyが動作します。

この性質がLiteLLM単体の問題にとどまらない理由です。.pthファイルの自動実行はあらゆるpipパッケージが利用できる仕組みのため、同種の手口は他のライブラリでも再現可能です。アーキテクチャ上の脆弱点は「LiteLLMのコード品質」ではなく「pipのパッケージインストール時に任意コードが実行されうる設計そのもの」にあります。

最後に、wheelのRECORDハッシュやプラットフォーム整合性が正常だった点も見逃せません。これは攻撃者が盗んだトークンで改変済みwheelを手動アップロードしたのではなく、プロジェクト自身の(非公開の)リリースパイプラインが、改ざんされたソースからビルドした結果である可能性を示しています。サプライチェーンのどの段階が侵害されたのかを特定する難しさが、ここに表れています。

自分のプロジェクトが該当するか確認する方法

まず該当バージョンを使っていないか確認します。

pip show litellm

Version: 1.107.0と表示された場合は要注意です。現在PyPI上では1.107.0は削除され、pip install litellmは1.106.2に解決される状態になっています。削除はyank(警告付きで残す措置)ではなく完全な除去であり、リリース一覧からも消えています。

次に、site-packages内に見覚えのないファイルがないか確認します。

find $(python -c "import site; print(site.getsitepackages()[0])") -maxdepth 1 -name "*.pth" -o -name "sitecustomize.py"

cook.pthやsitecustomize.pyのような、インストールした覚えのないパッケージが作成していないファイルが見つかった場合は、内容を必ず目視確認してください。

併せて、CI/CDのビルドログを遡り、10月21日前後にlitellm==1.107.0や範囲指定(例: litellm>=1.100)でのインストールが走っていないかも確認しましょう。Dockerイメージをキャッシュしている場合は、その時期にビルドされたレイヤーも対象です。

対策の手順

バージョン固定の見直しが最初の一歩です。requirements.txtやpyproject.tomlでlitellmを範囲指定していないか確認し、litellm==1.106.2のようにハッシュ付きで固定します。

pip install litellm==1.106.2 --require-hashes

pip-compile(pip-toolsに含まれるロックファイル生成コマンド)やpoetry lockを使っている場合は、ロックファイルを再生成し、差分で意図しないバージョン変更が紛れていないか確認してください。

次に侵害されたと仮定した場合の資格情報ローテーションです。もし該当期間にインストールした形跡があるなら、SSHキー、クラウドの認証情報(AWS IAMキー、Azureのサービスプリンシパル、gcloudのサービスアカウントキー)、CI/CDのシークレットはすべて失効・再発行する判断が必要です。影響範囲が広いため、該当ホストで動いていた全プロセスの資格情報を疑う姿勢が安全側に倒れます。

最後にサプライチェーンの監視体制です。依存ライブラリの自動更新(Dependabotやrenovateなど)を使っている場合、マイナーバージョンやパッチバージョンの自動マージを無条件に許可していないか見直します。少なくともLLM関連ライブラリやシークレットを扱うライブラリについては、更新をいったん人の目でレビューする運用に切り替える判断材料になります。

.pthファイルとsitecustomizeによる起動時自動実行は、importの有無に関わらず動くPythonの仕様であり、特定ライブラリのバグ修正だけでは再発を防げません。

まとめ

LiteLLM 1.107.0の一件は、約2時間という短い公開期間でも深刻な被害を生みうることを示しました。確認すべきことを整理します。

  • pip show litellmでバージョンを確認し、1.107.0なら直ちに1.106.2以降の安全なバージョンへ固定する
  • site-packages内の.pthファイルとsitecustomize.pyを定期的に棚卸しし、見覚えのないものがないか確認する
  • CI/CDのロックファイル運用を見直し、依存ライブラリの自動更新をレビューなしでマージしない体制にする
  • 侵害の疑いがある場合はSSHキー・クラウド認証情報・CI/CDシークレットを広めに失効・再発行する

Pythonのパッケージエコシステムは便利さと引き換えに、インストール時のコード実行という大きな信頼を前提にしています。依存関係の固定とロックファイルの運用を今一度見直す機会にしてみてください。

参考

LiteLLM 1.107.0 stole credentials from every Python process. I checked PyPI and reproduced the mechanism with a canary

この記事について: 本記事は AI を活用して作成し、forva AI 編集部が内容を確認・監修しています。

AI 駆動開発のご相談は forva AI へ。まずはお気軽にどうぞ。