cat posts/%e4%bb%8a%e9%80%b1%e3%81%ae%e3%82%bb%e3%82%ad%e3%83%a5%e3%83%aa%e3%83%86%e3%82%a3%e8%80%83%e5%af%9f%ef%bc%9a%e4%bf%a1%e9%a0%bc%e3%81%97%e3%81%a6%e3%81%84%e3%81%9f%e6%a5%ad%e8%80%85%e3%81%8c40%e5%88%86.md

今週のセキュリティ考察:40分の公開で2,100組織に届いた——LiteLLM PyPI サプライチェーン攻撃

AI モデルの API をまとめて呼び出せる Python ライブラリ LiteLLM の悪性バージョン 1.82.7 と 1.82.8 が、2026年3月24日に約40分間、配布サイト PyPI に公開されていた[1][5]。

PART 1解説

3行でわかる要点

  • 盗まれるもの:環境変数、SSH の鍵、クラウドの認証情報、Kubernetes のトークン、データベースのパスワードなどを集め、暗号化して攻撃者のドメインに送っていた[5]。
  • 規模:CloudSEK は、攻撃者が集めた約43万4千件のファイルから、2,500 を超える組織に影響した可能性があるとした。これは被害件数ではない[3][5]。
  • 経緯:セキュリティスキャナー Trivy を狙った一連の攻撃(TeamPCP)で漏れた公開用の API トークンが使われ、2つの版が PyPI にアップロードされた[2][4][5]。

前提:ライブラリの配布と依存関係

Python や JavaScript の開発では、他の人が作ったライブラリを PyPI や npm といった公開の置き場から取り込んで使います。LiteLLM は、OpenAI や Anthropic など複数の AI モデルの API を、同じ書き方で呼び出せるようにするライブラリです。

こうしたライブラリはさらに別のライブラリに依存していて、1つ入れると数十のライブラリが一緒に入ることも珍しくありません。その鎖のどこか1つが汚染されると、それを使う多くのシステムに一斉に被害が広がります。これがサプライチェーン攻撃と呼ばれる理由です。

まず押さえる用語

用語ひとことでもっと詳しく
サプライチェーン攻撃ソフトウェアの部品や配布の経路を汚染し、それを使う多くの利用者に被害を広げる攻撃。IPA「情報セキュリティ10大脅威」
PyPIPython のライブラリを配布する公式の置き場。pip install はここから取得する。PyPI
バージョンの範囲指定litellm>=1.0 のように「この版以上」と指定すること。新しい版が出ると自動で取り込まれる。pip「Secure installs」
推移的依存自分が直接使うライブラリが、さらに使っているライブラリ。自分で選んでいなくても入ってくる。—

本来の仕組みと、どこが破られたか

ライブラリ公開の正常時と攻撃時正常時開発者が変更公式の CI でビルドPyPI に公開利用者が取得攻撃時トークンが漏れる公式の CI でビルド悪性版を直接公開自動で取得される
図1 公式のビルドを通さずに、悪性の版が直接 PyPI にアップロードされた(LiteLLM・The Hacker News の記述をもとにした概念図)

通常、ライブラリの新しい版はプロジェクトの公式のビルド手順(CI)を経て PyPI に公開されます。LiteLLM の調査では、悪性の2つの版は公式の CI を通らず、直接 PyPI にアップロードされていました[5]。

使われたのは、Trivy への攻撃で漏れた公開用のトークンです[2][5]。図1の赤い破線が、飛ばされた「公式の CI でビルド」の段階です。トークンさえあれば、正規の手順を通らずに「公式の新しい版」として公開できてしまいます。

攻撃の流れ

sequenceDiagram
    autonumber
    participant A as 攻撃者
    participant P as PyPI
    participant C as CI/CD
    participant E as 実行環境
    A->>P: 漏れたトークンで悪性のLiteLLMを公開
    Note over P: 約40分間公開
    C->>P: pip install(範囲指定で最新版を取得)
    P-->>C: 悪性パッケージを返す
    C->>E: Python起動時に悪性コードが動く
    E->>A: 認証情報を暗号化して送信
  • 1.82.8 には、Python の起動時に自動で読み込まれる litellm_init.pth が含まれ、LiteLLM を import しなくても動いた[5]。
  • LiteLLM は、3月24日 16:00 UTC までにインストールした環境は疑ってかかるよう案内している[1][5]。

なぜ40分で多くの組織に届いたのか(考察)

  • 多くの CI/CD は、ビルドのたびに pip install で依存ライブラリを取得する。範囲指定のままだと、悪性の版が出た瞬間に世界中のパイプラインが一斉に取り込む。
  • 自分で LiteLLM を選んでいなくても、エージェントのフレームワークなどを通じて推移的依存として入りうる[5]。
  • セキュリティスキャナーの周辺が攻撃の入口になった。「守りのツール」も供給網の一部として扱う必要がある[4][5]。

いま確認すること

  • 【該当期間に Python 環境を構築した】LiteLLM 1.82.7 / 1.82.8 が入っていないか確かめ、入っていたら認証情報をすべて変更する[1][5]。
  • 【全員】requirements.txt や package.json で、依存ライブラリをバージョンの範囲指定のままにしていないか確かめる。
  • 【全員】lock file を作り、ハッシュの検証まで行っているか確かめる。ここが実際の防御線になる[6]。
# 範囲指定(危険:常に最新版を取得する)
litellm>=1.0
# バージョン固定+ハッシュ検証(推奨)
litellm==1.83.0 --hash=sha256:...
# pip-compile で lock file を生成する
pip-compile --generate-hashes requirements.in
  • 【全員】依存ライブラリの更新通知を、誰がいつどう確かめるかを決めているか確かめる。自動マージが野放しになっていないかも見る。

出典・参考リンク

一次情報

  1. LiteLLM — Security Update March 2026
  2. PyPA Advisory Database — PYSEC-2026-2

報道・解説

  1. CloudSEK — AI supply chain breach の調査
  2. Aqua Security — Trivy supply chain attack
  3. The Hacker News — Malicious LiteLLM Releases Tied to Trivy Hack

用語解説

  1. pip — Secure installs(ハッシュ検証)

PART 2問題(情報処理安全確保支援士 試験形式)

問1 午前II形式(4択)

LiteLLM の悪性バージョンが、公開から約40分という短時間で多くの組織に届いた可能性がある主な理由として、最も適切なものはどれか。

  • ア 悪性バージョンが PyPI の検索結果で上位に表示されたから
  • イ 多くの CI/CD パイプラインが、範囲指定した依存関係をビルドのたびに最新版で取得していたから
  • ウ 攻撃者が各組織に個別にフィッシングメールを送ったから
  • エ LiteLLM が Python に標準で同梱されていたから
解答・解説を表示

解答:イ

litellm>=1.0 のような範囲指定のままだと、悪性の版が公開された瞬間に世界中のパイプラインが一斉に取得する。アとウは人が操作する経路で、40分で広がった理由にならない。エは事実と異なる。

↑ Part 1「なぜ40分で多くの組織に届いたのか」を読み直す

問2 午後形式(記述)

A社の CI/CD パイプラインは、ビルドのたびに pip install -r requirements.txt を実行している。requirements.txt には litellm>=1.0 と書いている。LiteLLM の悪性バージョンが PyPI に公開された件を受けて、A社は①依存パッケージの指定方法を見直すことにした。

設問 本文中の下線①について、どのように見直すべきかを50字以内で述べよ。

解答・解説を表示

解答例:バージョンを固定し、ハッシュ検証付きの lock file を生成してそれでインストールする(46字)

pip-compile --generate-hashes などでバージョンとハッシュを固定すれば、公開直後の悪性の版を自動で取り込まない。「常に最新版へ更新する」は、今回の被害を広げた動きそのもの。固定したあとは、更新の通知を誰がいつ確かめるかも決めておく。

↑ Part 1「いま確認すること」を読み直す