aighten
← ブログに戻る

LiteLLM 1.107.0侵害:影響の確認方法と対処法

LiteLLM 1.107.0LiteLLM 侵害LiteLLM サプライチェーン攻撃PyPI マルウェアcook.pth+2 more
LiteLLM 1.107.0侵害:影響の確認方法と対処法

LiteLLM 1.107.0侵害はソフトウェアサプライチェーン攻撃です。2026年10月21日、攻撃者はLiteLLM自身のリリースパイプラインを悪用し、悪意ある litellm==1.107.0 をPyPIとプロジェクトのDockerイメージに公開しました。このリリースは、認証情報を盗むスティーラーと、1時間ごとにリモートコードを読み込むローダーを仕込みます。これらはコードがLiteLLMをimportしているかどうかに関係なく、Pythonが起動するたびに実行されます。1.107.0を実行したマシン、CIジョブ、コンテナがひとつでもあれば、LiteLLMのインシデントレポートは、それを侵害済みとして扱い、ゼロから再構築し、到達可能だったすべてのシークレットをローテーションするよう求めています。

PyPIでの公開期間は2時間未満で、UTC 11:39:51から13:23頃まで(日本時間20:39から22:23頃まで)でした。それでも、このプロジェクトにとっては影響が出るのに十分な時間です。LiteLLMのPyPIダウンロード数は、確認時点の直近1日で約340万回、過去1か月で約9,200万回にのぼります(pypistats、2026年10月22日取得)。また、LiteLLMのリリースプロセスが侵害されたのは今年に入って2回目です。

要点まとめ

  • 悪意があるのは litellm 1.107.0のみです。7つのwheelすべてにペイロードが含まれていました。LiteLLMは、1.106.2またはインシデント以前に公開された任意のバージョンに固定するよう推奨しています。
  • Dockerイメージも被害を受けました。GHCRとDocker Hubの v1.107.0、latest、main-latest、main-stable タグは、11:46:56 UTCから13:51(GHCR)および14:20 UTC(Docker Hub)まで、汚染されたイメージを指していました。
  • ペイロードは、SSH鍵、クラウドおよびKubernetesの認証情報、CI/CDシークレット、AIコーディングツールのトークン、LiteLLMプロキシのデータベースに保存されたLLMプロバイダーのキーを盗み、その後は1時間ごとに攻撃者から追加のコードを読み込もうとします。
  • 攻撃者は、LiteLLM開発者3人から盗んだGitHub CLIの認証情報で侵入し、ブランチ保護を上書きして、非公開のリリースワークフローを類似名のリポジトリ Berri-AI/litellm に向けました。
  • パッケージをアンインストールするだけでは不十分です。インプラントのファイルを削除し、バックグラウンドのデーモンを停止し、環境を再構築したうえで認証情報をローテーションしてください。

LiteLLM 1.107.0に何が起きたのか

LiteLLMはBerriAIが開発するオープンソースのPythonライブラリ兼プロキシサーバーで、100以上のモデルプロバイダーの前段にOpenAI形式の単一APIを提供します。多くのチームがこのプロキシを社内のLLMゲートウェイとして使っているため、通常はOpenAI、Anthropic、Google、AWS Bedrockなどのキーがそのデータベースに保存されています。GitHubリポジトリのスター数は約6万2,000です。

LiteLLMのインシデントレポートによると、攻撃者は開発者3人分のGitHub CLI認証情報を握っていました。10月21日 10:08:29 UTC、非公開のリリースワークフローに対する不正な変更がブランチ保護によって拒否されました。その5秒後、GitHub組織のオーナーに属する認証情報がこの保護を上書きし、変更を適用しました。改ざんされたワークフローは、本物の BerriAI/litellm とハイフン1つだけ名前が異なるリポジトリ Berri-AI/litellm からリリースをビルドしました。盗まれた2つ目の認証情報が本番ゲートを承認し、パイプラインは成果物に署名して公開しました。

汚染された成果物はLiteLLMの正規パイプラインから出力されたもので、PyPIトークンが乗っ取られたわけではありません。SafeDepの調査によると、wheelのビルドメタデータはBerriAIの通常のツールと一致しており、GitHub上の公式 v1.107.0 タグには悪意あるファイルが含まれていません。GitHubのソースと公開パッケージの差分を取れば問題は見つかったはずですが、パッケージが公式パイプラインから来たかどうかを確認するチェックは通過していたことになります。

LiteLLMはトークンが漏えいした経緯も説明しています。レポートによれば、Claude Codeはレスポンスボディにユーザーの GitHub CLI OAuthトークンを含めることがあり、レスポンスボディをログに記録している場合、そのトークンがLiteLLMのログに残る可能性があります。インターネットに公開されていたLiteLLMの社内デプロイメント上に想定外のユーザーアカウントが存在し、攻撃者はそれを使ってログを読み取りました。LiteLLMは最近修正された脆弱性が使われたと見ていますが、レポートの最終更新時点では侵入経路を特定できていませんでした。

攻撃のタイムライン(UTC、2026年10月21日)

時刻出来事
10:08:29ブランチ保護がリリースワークフローへの不正な変更をブロック
10:08:34組織オーナーの認証情報が保護を上書きし、変更を適用
10:46:39類似名リポジトリからビルドするステージング実行が開始
11:11:182人目の開発者の認証情報が本番ゲートを承認
11:39:51から11:40:13悪意あるwheel 7つがPyPIにアップロードされる
11:43:05AISLEの依存関係ファイアウォールが最初のwheelを検知
11:46:56悪意あるDockerイメージが公開される
11:53:493つ目の認証情報がワークフローの実行記録を削除
13:23PyPIが litellm==1.107.0 を削除
13:51GHCRのタグが利用不可になる
14:20Docker Hubの全タグが削除、またはクリーンなイメージへ付け替えられる

出典:LiteLLMのインシデントレポート。検知時刻はAISLEによる。

AISLEによると、同社のスキャナーはアップロードから3分14秒後に最初のwheelを検知し、12:00 UTCまでに7つすべてを検知しました。PyPIがリリースを取り下げたのはアップロードから約1時間40分後で、Docker Hubのタグは約2時間半にわたって不正なイメージを配信し続けました。

悪意あるパッケージの挙動

各wheelは、site-packages に3つの余分なファイルを配置します。Pythonのsiteモジュールは、import行を含む .pth ファイルと sitecustomize モジュールを、インタープリターの起動時に自動で実行します。そのため、ペイロードはマシン上のあらゆるPythonプロセスで実行されます。pip、テストランナー、IDEの言語サーバー、CIジョブも例外ではなく、LiteLLMにまったく触れないプロセスでも動きます。

ファイル役割
cook.pthPythonが起動するたびに import cook を実行
cook.py約60KBの難読化された認証情報窃取コード
sitecustomize.py親から切り離されたバックグラウンドデーモンを起動し、1時間ごとにリモートコードを取得して実行

ステージ1:認証情報スティーラー

SafeDepは cook.py 内に16個の収集モジュールを確認しました。収集対象は、システムとネットワークの情報、ブラウザのパスワードと閲覧履歴、SSH鍵、シェル履歴、AWS・Azure・GCP・Kubernetes・Dockerの認証情報、.pem と .key ファイル、GitLab・Jenkins・Terraform・Vaultのシークレット、Claude Code、Cursor、Copilot、CodexといったAI開発ツールのトークン、他プロセスの環境変数、AWSインスタンスメタデータの認証情報、GPG鍵、TLS秘密鍵です。

LiteLLMプロキシの場合、スティーラーはLLMプロバイダーのAPIキーを保持するデータベーステーブルも読み取ります。データは暗号化(AES-256-CBC、鍵はRSAでラップ)されたうえで、本物の litellm.ai ドメインに似せた www.litellm[.]dev にアップロードされます。実行はホストごとに1回で、/tmp にマーカーファイルを残します。

ステージ2:1時間ごとのローダー

sitecustomize.py は親プロセスから切り離されたデーモンをforkし、/tmp/remote_code_loader.lock でロックを保持します。このデーモンは1時間ごとに、攻撃者が管理するGitHubリポジトリ内のファイルからサーバーのアドレスを読み取り、スティーラーを再実行し、そのサーバーからPythonコードをダウンロードして実行します。StepSecurityがこのファイルの履歴を調べたところ、リリース前日の10月20日に中身が空にされていました。AISLEも空であることを確認しているため、第2段階は一度も有効化されなかったとみられます。背後にあるGitHubアカウントは13:40 UTC頃までに消えていました。ただしSafeDepは、それ以前に一部のホストが第2段階のコードを取得していた可能性を依然として否定していません。Windowsでは、ローダーがUnix専用の呼び出しに依存しているため失敗しますが、スティーラーは実行されます(StepSecurity)。

盗まれた鍵は数時間以内に悪用された

Wizの報告によると、CIランナーとKubernetesノードから盗まれたAWSインスタンスロールの認証情報が、16:20から17:01 UTCの間、つまりリリースから約4時間半後に試されました。攻撃者は sts:GetCallerIdentity と bedrock:ListFoundationModels を呼び出しており、Wizはこのパターンを LLMjacking(被害者のクラウドアカウントを使って有料のAIモデルを動かす手口)と結び付けています。盗まれた認証情報の悪用を報告しているのは、現時点でWizのみです。

LiteLLM侵害の影響を受けているか確認する方法

2026年10月21日以降のいずれかの時点で、次のいずれかが実行されていた場合は影響を受けています。

  1. litellm==1.107.0 がインストールされたPython環境。LiteLLMのチェックリストでは pip show litellm を使いますが、侵害が疑われるマシンでこのコマンドを実行するとPythonが起動し、インプラントが再実行されてしまいます。まずはPythonを使わずに確認してください。ロックファイル(uv.lock、poetry.lock、requirements*.txt)で 1.107.0 を検索し、find で litellm-1.107.0.dist-info フォルダや cook.pth を探します。
  2. ghcr.io/berriai/litellm、litellm-database、litellm-non_root、またはDocker Hubのイメージから起動したコンテナのうち、上記の時間帯に v1.107.0、latest、main-latest、main-stable タグでpullしたもの。LiteLLMは、侵害されたDocker Hubのインデックスダイジェストとして sha256:1bbcb1443bc962e45f5aad53fe3d2c30600e0379715fb6c664cdd3ac126c339e を挙げています。
  3. PyPIでの公開時間帯に、バージョンを固定せずにLiteLLMをインストールしたCIジョブ。

ホスト上で探すべき痕跡は次のとおりです。

  • 任意の site-packages ディレクトリ内にある cook.pth、cook.py、sitecustomize.py、および litellm-1.107.0.dist-info フォルダ
  • /tmp/.pc_once_72129118c59f5636c0bb(スティーラーがすでにデータをアップロード済み)と /tmp/remote_code_loader.lock(ローダーが実行された)
  • Pythonプロセス内の環境変数 PRIVCOLLECT_ACTIVE=1
  • 親PIDが1で、作業ディレクトリが / になっている、切り離されたPythonプロセス
  • www.litellm[.]dev または raw.githubusercontent[.]com/letters9813/... への外向き通信、およびPythonプロセスから 169.254.169.254 へのリクエスト

LiteLLMのレポートは、これらが見つからなくてもホストがクリーンである証明にはならないと強調しています。

LiteLLMによれば、影響を受けないのは、1.106.2や1.107.0のリリース候補版を含むそれ以前のリリースと、LiteLLMの非公開レジストリからpullしているエンタープライズ顧客です。

クリーンアップ手順とローテーション対象

LiteLLMが示している手順は、次の順番のとおりです。

  1. 影響を受けた環境で、最初に pip install を実行しないでください。Pythonが起動するたびにインプラントが再実行されます。
  2. 影響を受けたすべての site-packages から、cook.pth、cook.py、sitecustomize.py と、それらの __pycache__ 内のコピーを削除します。
  3. /tmp/remote_code_loader.lock を保持しているデーモンを停止します。
  4. litellm==1.106.2 に固定して再インストールします。可能であれば、仮想環境とイメージをゼロから再構築するほうが確実です。
  5. ホストが外部インターネットに接続できた場合は、データが持ち出されたものとみなしてください。インスタンスまたはタスクのIAMロール、LiteLLMプロキシのデータベースに保存されたすべてのプロバイダーキー、LiteLLMのマスターキーと仮想キー、DATABASE_URL のパスワード、そしてホスト上のあらゆるプロセスの環境変数に含まれるシークレットをローテーションします。
  6. AWSの場合は、インストール時刻の前後にインスタンスロールから GetCallerIdentity が呼び出されていないか、またそのロールの認証情報が自社ネットワークの外から使われていないかを、CloudTrailで確認します。

開発者のノートPCにも同じ対応が必要です。スティーラーはClaude Code、Cursor、Copilot、Codexのトークン、SSH鍵、ブラウザに保存されたパスワードを狙うため、1.107.0をインストールしたノートPCではこれらも再発行してください。

LLMゲートウェイがサプライチェーン攻撃の格好の標的になる理由

LiteLLMのようなゲートウェイには、企業が利用するすべてのモデルプロバイダーのキーが集まり、多くの場合はクラウドの認証情報やデータベースも同じ場所にあります。そのマシン上の依存関係がひとつ汚染されるだけで、1つのアプリケーションをはるかに超える範囲が危険にさらされます。

2026年に入って、これが2回目です。3月には、LiteLLMのCIで使われていたTrivyの依存関係が侵害され、そこから盗まれた認証情報を使って、LiteLLM 1.82.7と1.82.8が認証情報スティーラー入りで公開されました。10月のレポートによると、この事件を受けてチームはリリースを非公開リポジトリに移し、Trusted Publishingを導入し、Dockerタグをイミュータブルにし、イメージへの署名を始めました。10月の攻撃者は、正規のパイプライン内で本物のメンテナー認証情報を使うことで、これらすべてをすり抜けました。

利用者側にとっての教訓は、署名やPyPIのattestationが証明するのはパッケージがどこでビルドされたかであって、ビルドの入力が自分たちのレビューしたコードだったことではない、という点です。SafeDepによれば、1.107.0にはPyPIの来歴(provenance)attestationがそもそも付いておらず、クリーンな1.106.2にも付いていませんでした。そのため、attestationのチェックでは異常は何も検出されなかったはずです。次の3つの習慣があれば、今回のインシデントは食い止められていました。

  • ハッシュ付きで正確なバージョンを固定し(pip install --require-hashes、または uv やPoetryのロックファイル)、ビルドのたびではなく意図したタイミングで更新します。
  • latest や main-stable のような変動するタグではなく、ダイジェストでDockerイメージを固定します。
  • 新しいリリースは、本番環境に取り込む前に1日から2日のクーリング期間を置きます。uv は exclude-newer 設定でこれに対応しており、依存関係ファイアウォールを使えば悪意ありと判定されたパッケージをブロックできます。AISLEの検知はアップロードの約3分後、PyPIによる隔離は約100分後でした。

LiteLLMがこれまでに実施した対策

レポートには4つの対応が挙げられています。PyPIからのパッケージ削除、メンテナー認証情報の失効と必要最小限への権限縮小、悪意あるワークフローのリビジョン削除と以前のバージョンへの復元、そして影響を受けたDockerタグの削除または検証済みのクリーンなイメージへの付け替えです。10月21日 20:30 UTCのレポート更新時点で調査は継続中で、LiteLLMは侵害の痕跡に関する追加情報を公開するとしています。

よくある質問

安全なLiteLLMのバージョンはどれですか?

LiteLLMによると、1.107.0より前のバージョンはすべて安全で、1.106.2への固定を推奨しています。SafeDepも1.107.0rc1と1.107.0rc2をクリーンとしています。ペイロードが含まれていたのは、PyPI上の正式版1.107.0と、インシデントの時間帯にタグ付けされたDockerイメージだけです。

コードでLiteLLMをimportしていなくても危険ですか?

はい、その環境に1.107.0がインストールされていた場合は危険です。ペイロードは、Pythonが起動時に実行する .pth ファイルと sitecustomize.py を利用しています。そのため、その環境のあらゆるPythonプロセスで、pip 自体も含めて実行されています。

LiteLLM 1.107.0をアンインストールするだけで十分ですか?

いいえ。インプラントのファイルは site-packages に残り、1時間ごとのデーモンも動き続け、盗まれた認証情報も有効なままです。LiteLLMは、ファイルの削除、デーモンの停止、環境の再構築、そしてホストから到達可能だったすべての認証情報のローテーションを推奨しています。

LiteLLMのDockerイメージも影響を受けましたか?

はい。ghcr.io/berriai/litellm、litellm-database、litellm-non_root の v1.107.0、latest、main-latest、main-stable タグは、11:46:56 UTCから、GHCRでは13:51 UTCまで、Docker Hubでは14:20 UTCまで、侵害されたイメージを指していました。それ以前のダイジェストやバージョンに固定していたイメージは影響を受けていません。

攻撃者はどうやってLiteLLMの公式パイプラインから公開したのですか?

LiteLLM開発者3人から盗んだGitHub CLIの認証情報を使いました。そのうち1つは組織オーナーのもので、ブランチ保護の上書きに使われました。改ざんされたワークフローは類似名のリポジトリ Berri-AI/litellm からビルドを行い、2つ目の認証情報が本番リリースを承認しました。

出典

Share this post