AIモデルへのアクセスを統合・管理するソフトウェア「LiteLLM」のバージョン1.107.0に、認証情報を盗むマルウェアと遠隔コードを実行する仕組みが混入していたことが分かった。不正なパッケージは2026年10月21日にPyPIとDockerレジストリを通じて配布され、開発元は問題の配布物を削除し、事案を封じ込めたと発表している。LiteLLMは同年3月にも侵害を受けているが、今回は正規のGitHubタグに悪性ファイルが存在せず、別のリポジトリから作られた不正な配布物が正式な承認工程を通過していた。さらに、インストール後はLiteLLMを使用しないプログラムでも、通常のPython起動時に窃取コードが実行される恐れがある。正規のソースコードを確認するだけでは安全性を判断できず、実際に配布されたファイルと稼働環境まで調査する必要がある事案だ。

AD

正規の承認工程を通過した不正な配布物

開発元の公式報告によると、今回の攻撃には3人の技術者のGitHub認証情報が悪用された。GitHub CLIのOAuthトークンが盗まれたとみられるが、攻撃者がどのようにトークンを入手したのかは、現時点で解明されていない。公式の時系列によれば、攻撃者によるリリース工程への不正な変更は、当初ブランチ保護機能によって拒否されていた。しかし、特権アカウントの認証情報を使って保護設定が上書きされ、別のアカウントによって本番公開が承認された。さらに、別の認証情報を使って、調査に必要なワークフローの記録も削除されたという。変更者と承認者を分離する仕組みを設けていても、双方の認証情報を奪われれば、その保護を突破されることが今回の経緯から分かる。

不正な配布物が作られたリポジトリも、正規のものとは異なっていた。LiteLLMの公式リポジトリはBerriAI/litellmだが、問題の配布物は名前にハイフンが入ったBerri-AI/litellmからビルドされていた。公式のv1.107.0ソースタグには今回の悪性ファイルが含まれておらず、ソースコードを調べただけでは、実際に利用者へ届けられたファイルの問題を発見できない状態だった。

セキュリティ企業Socketは、独自調査でコンテナのビルド来歴情報を分析し、この食い違いを確認している。調査対象となったLinux amd64イメージには、ソースの所有者としてBerri-AIが記録されていた。また、そのリポジトリに存在する悪性ファイルは、Socketが検査したPyPIのwheelファイルとバイト単位で一致していた。一方、直前のバージョン1.106.2では、ビルド来歴が正規のBerriAIを指していた。こうした来歴情報は、配布物がどのソースから作られたかを追跡する重要な手掛かりになるが、ビルド元の安全性そのものを保証するわけではない。

開発元の詳細報告によると、不正な配布物が提供されていた期間は以下のとおりだ。時刻はいずれも2026年10月21日の協定世界時(UTC)である。

配布先 影響を受けたバージョン・タグ 不正な配布物が提供された期間
PyPI litellm==1.107.0の全7本のwheel 11:39:51〜13:23
Docker Hub v1.107.0、latest、main-latest、main-stable 11:46:56〜14:20
GHCR 同じタグのLiteLLM関連イメージ 11:46:56から提供。13:51までに停止を確認

latestなど、参照先が更新されるタグを使用していた環境では、1.107.0を明示的に指定していなくても、不正なイメージを取得した可能性がある。また、配布が停止された後も、ローカルキャッシュや既存のコンテナイメージに不正なファイルが残っている場合があるため、引き続き調査が必要だ。開発元は、非公開の企業向けレジストリからLiteLLMを取得している顧客は今回の影響を受けていないと説明している。一方、オープンソース版の利用者には、バージョン1.106.2など、安全性が確認された旧バージョンへの固定を求めている。

LiteLLMを読み込まなくても動作する認証情報窃取コード

GMO Flatt Securityは、自社のTakumi Guard解析基盤による調査を通じて、不正なwheelファイルにcook.pth、cook.py、sitecustomize.pyの3ファイルが追加されていたことを報告している。これらのファイルは、インストール時にLiteLLMのライブラリ本体ではなく、Python環境のsite-packagesディレクトリ直下へ配置される。重要なのは、この配置によってLiteLLMを直接使用しないプログラムにも影響が及ぶ可能性があることだ。

cook.pthにはimport cookという命令が記述されており、Pythonの起動時に認証情報を収集するコードを読み込ませる。もう一つの入口となるsitecustomize.pyも、Pythonが起動時に自動で読み込もうとするファイルだ。Pythonの公式ドキュメントには、.pthファイル内の実行可能な行やsitecustomizeの読み込みについて説明されている。攻撃者はこうした標準的な起動処理を悪用しているため、アプリケーション側でLiteLLMを明示的にインポートする必要はない。悪性ファイルが残ったPython環境では、通常のプログラムを起動するだけでも窃取コードが実行される恐れがある。

SocketとGMO Flatt Securityの解析によると、認証情報の収集コードはprivcollectという名称を使用し、16の収集モジュールを備えている。標的はクラウドサービスの認証情報にとどまらず、SSH秘密鍵やブラウザに保存されたデータにも及ぶ。また、Codex、Claude、GeminiなどのAI開発ツールが使用する認証・設定ファイルも探索するほか、Linuxでは権限上読み取り可能な他プロセスの環境変数から情報を取得しようとする。つまり、同じマルウェアに感染しても、開発者の端末、CI環境、AIゲートウェイなど、実行場所によって流出する恐れのある情報は異なる。

LiteLLM自体が管理する認証情報も標的となっている。環境変数DATABASE_URLが設定されている場合、マルウェアは認証情報を保存するLiteLLM_CredentialsTableや、モデル設定を保持するLiteLLM_ProxyModelTableへの問い合わせを試みる。LiteLLMは複数のAIサービスのAPIキーを一元管理できるため、侵害された環境によっては、多数のサービスの認証情報が危険にさらされる可能性がある。このため、ファイルに保存されたAPIキーだけを交換しても、十分な対処にはならない。ただし、データベースへのアクセスを試みるコードが存在することと、実際に個々の環境からすべての情報を取得・復号できたことは区別する必要がある。

収集した情報の送信先には、正規の診断処理を装うようなwww[.]litellm[.]dev/healthcheckが指定されていた。Socketによると、マルウェアは収集データをAES-256-CBCで暗号化し、その暗号鍵をRSA-4096の公開鍵で保護して送信する仕組みを備えている。URLにはヘルスチェックを思わせる名称が使われているものの、実際には認証情報などを外部へ持ち出すための通信先である。

さらに、認証情報の窃取とは別に、外部から取得したPythonコードを実行する仕組みも組み込まれていた。sitecustomize.pyから起動する常駐プロセスは、GitHub上のletters9813/pythonclient-testに置かれたdomain.txtを参照する。このファイルに有効な接続先が指定されていれば、そこからPythonコードを取得し、署名やハッシュによる内容の検証を行わずに実行する設計だ。接続先の確認後は1時間待機する仕組みになっているが、これは1時間ごとに認証情報の窃取が成功していたことを意味するものではない。

ただし、マルウェアの動作にはOSや実行環境による制約もある。JFrogの静的解析によると、Windowsではos.fork()に依存する常駐プロセスの起動処理を完了できない一方、cook.pthを通じた認証情報の窃取経路は残る。また、Socketが調査したmacOS向け配布物では、一部のデータベース処理やブラウザのパスワードを平文で取得する処理に制限が確認された。Socketが10月21日13時01分44秒(UTC)に確認した時点では、遠隔コードの取得先を指定するdomain.txtも空だった。しかし、遠隔コードの実行経路が機能しなかったとしても、独立して動作する認証情報収集コードまで無効になるわけではない。特定の機能が動作しないことを、環境全体が安全である証拠とみなすことはできない。

AD

復旧には配布物・実行環境・認証情報の個別確認が必要

開発元は、影響を受けた可能性がある環境では、pip installを使った修復作業から始めないよう注意を促している。pip自体もPythonで動作するため、状態を確認したりパッケージを入れ直したりする過程で、悪性ファイルが再び実行される恐れがあるためだ。Socketも、信頼できるツールで証拠を保全し、影響を受けたホストやコンテナを隔離したうえで、環境を再構築するよう勧めている。単にLiteLLMをアンインストールするだけでは、Pythonの起動処理に組み込まれた悪性ファイルや常駐プロセスが残る可能性がある。

今回の事案では、正規のソースタグ、実際の配布物、稼働中の環境をそれぞれ別の対象として検証する必要がある。公式タグに問題がなく、配布元から不正版が削除されたとしても、すでに導入された環境の安全性は証明できない。開発元の公式報告とSocketによる起動処理の解析を基に、確認すべき対象と、それぞれの証拠から判断できる範囲を整理すると以下のようになる。

確認する対象 今回の判断材料 それだけでは分からないこと
ソースタグ 公式タグに悪性ファイルが含まれていないこと 実際に配布されたwheelやコンテナイメージが安全かどうか
配布物とビルド来歴 実ファイル、ビルド元の所有者・リビジョン、稼働イメージのダイジェスト インストール後に何が実行されたか
実行環境 起動関連ファイル、常駐プロセス、通信記録、導入履歴 証跡がない場合に、情報漏えいを否定できるか
認証情報 プロセスから読み取れた鍵、データベース、クラウド権限 マルウェアの除去だけで、流出した鍵の悪用を防げるか

配布停止によって防げるのは、不正なパッケージが新たに取得されることだ。すでに不正版を導入した環境では、LiteLLM本体を削除しても、site-packages直下の悪性ファイルや常駐プロセスが残る可能性がある。そのため、開発元はクリーンなコンテナイメージやPython仮想環境を使った再構築を推奨している。また、認証情報が外部へ送信された可能性がある場合は、感染環境とは別の安全な環境から該当する認証情報を失効させ、新しいものを発行しなければならない。マルウェアの除去と認証情報の失効は、それぞれ独立した対応として進める必要がある。

開発元が確認を求めている認証情報には、LiteLLMのプロキシデータベースに保存された各AIプロバイダーのAPIキーだけでなく、マスターキーや仮想キーも含まれる。さらに、データベースの接続パスワードや、実行環境から利用できたクラウドのIAMロールも調査対象となる。GMO Flatt Securityの解析で明らかになったAI開発ツールの認証情報も考慮すれば、調査範囲をLiteLLM専用のAPIキーだけに限定するのは適切ではない。実際に侵害されたプロセスがどのファイルやサービス、権限にアクセスできたかを確認し、流出した可能性のある認証情報を洗い出す必要がある。

一方、感染の痕跡となるマーカーファイルやロックファイルが見つからなくても、安全性を保証することはできない。コンテナの置き換えや一時ファイルの削除によって、痕跡が消える場合があるためだ。また、sitecustomize.pyはPythonの正規の仕組みでも使用されるため、このファイルが存在するだけで感染と判断することもできない。ファイル名の有無に頼らず、内容を調べるとともに、実行履歴や通信記録などを照合することが重要になる。

開発元は今回の事案を受け、関連するトークンを失効させ、GitHub組織への新規参加を一時的に制限するとともに、レジストリとの信頼連携も解除した。ただし、攻撃者が最初に認証情報を入手した経路については調査が続いており、3月の侵害と同じ攻撃者や侵入経路によるものだとする証拠も示されていない。今回明らかになったのは、リリースの承認履歴を残すだけでは、配布物の安全性を十分に保証できないという問題だ。あらかじめ許可されたリポジトリとリビジョンから生成された成果物だけに公開を認める仕組みが、サプライチェーンの保護において重要になる。利用者側でも、正規ソースの確認に加えて、実際に取得したパッケージや稼働中のコンテナイメージを照合し、配布から実行までの安全性を確かめる必要がある。