日本時間の2026年10月21日の夜、LiteLLM の 1.107.0 という版が、PyPI(Python の部品を配る公式の置き場)と Docker の登録所(Docker のイメージを配る置き場)に配られました。この版には、資格情報(パスワードや API キーのように、「その人だ」と認めてもらうためのもの)を盗む仕組みが入っていました。LiteLLM は、100 を超える AI のモデルの API を、OpenAI の形の 1 つの呼び方で呼べるようにするオープンソースのライブラリです。Python から直接使う形と、チームで 1 か所に置くサーバー(プロキシ。AI Gateway とも呼ばれます)の形があります。
LiteLLM の告知は、この版を "compiled malware"(マルウェア)と書いています。マルウェアとは、悪い働きをするように作られたプログラムのことです。ソフトの弱点(脆弱性)が見つかった件ではなく、悪い版そのものが、正規の配り場に出た件です(→「CVE の番号は付いている?」)。
先に答えを書きます。ここがいちばん大事なところです。時刻はすべて日本時間です(告知の UTC の時刻に 9 時間を足しました)。
- まず、時間と条件に当たる操作があったかを見ます。 告知が挙げる人は、次のとおりです(すべて10月21日の日本時間)。それより前の版は安全と、告知は書いています(→「自分の環境は当たる? 告知の条件で見る」)
- pip:20時39分〜22時23分 に、版を固定せずに(
pip install litellmのように番号を書かずに)LiteLLM を入れた人 - Docker:20時46分〜23時20分 に、イメージ(
v1.107.0・latest・main-latest・main-stable)を使った(起動した)人 - CI(自動でテストやビルドを回す仕組み):上の時間に、LiteLLM を入れた、またはそのイメージを使った実行があったか、実行の一覧の時刻で見ます
- pip:20時39分〜22時23分 に、版を固定せずに(
- 確かめるときは、疑わしい環境で Python を動かしません。 pip を動かすのも Python の起動です。ファイルの上で、告知の 3 つ(
litellm-1.107.0.dist-info・cook.pth・部品の置き場〔site-packages など〕のすぐ下のsitecustomize.py)を探します。Docker は、イメージを起動せずに、ダイジェスト(イメージごとの識別の文字列)を告知の値と比べます(→「どうやって確かめる? Python を動かす前にファイルを探す」) - 当たる操作があった、またはファイルが見つかったなら、乗っ取られたもの(盗まれた前提)として扱います。 告知の手順で、ファイルを消し、動き続けるプロセスを止め、環境を作り直し、その機械から手の届いた鍵やパスワードを全部替えます。インターネットに出られる機械なら、送り出しは成功したと考えるよう告知は書いています(→「入っていたら、何をする? 告知の手順」)
- LiteLLM を使い続けるなら、当たっていなくても、
litellm==1.106.2のように版を決めて入れます。 流すのは、当たる操作が無かった環境か、作り直した環境です。直った新しい版は出ていません。1.107.1 という版も PyPI にありません(2026年10月23日時点)(→「当たっていなくても:版を固定する」)
初心者がまずやることは、1 つ目です。上の時間に、自分のパソコン・サーバー・CI で、LiteLLM を入れる操作や、4 つのタグのイメージを使う操作があったかを、記録の時刻で見ます。次の人は、2 つ目の、Python を動かさずに告知の 3 つを探す手順に進みます。
- 記録が残っていなくて、分からない人
- 自分で入れた覚えが無い人(ほかの部品の依存で入ることがあります。→「LiteLLM を自分で入れた覚えがありません。関係ありますか?」)
- uv など、pip 以外で入れた人(告知は pip とだけ書いています。→「uv など、pip 以外で入れた人」)
書いてあることは、LiteLLM の告知・GitHub の issue・PyPI・Docker の登録所・公的機関の一覧などを、2026年10月23日の16時56分から17時7分ごろ(日本時間)に開いて確かめたものです。手元でファイルを探す手順・Docker の比べ方・文書の裏づけは、同じ日の17時45分から18時23分ごろに確かめました。悪い 1.107.0 そのものは、入れていませんし、落としてもいません。告知や公的機関の一覧は更新されることがあるので、時刻を添えました。
- 何が配られたか(LiteLLM 1.107.0)と、当たる時間(日本時間)。ソフトの弱点ではなく、悪い版そのものが配られた件であること
- 当たる人の条件(pip・Docker・CI)と、uv など pip 以外で入れた人の扱い
- Python を動かさずに確かめる方法(ファイルを探す、Docker はダイジェストを比べる)
- 入っていたときの告知の手順と、替える鍵
- 当たっていなくてもする、版の固定(1.106.2)
10月21日に、LiteLLM に何があった?
告知が書いていること
LiteLLM の公式の告知は、docs.litellm.ai のブログの記事です(Contained: Oct 21, 2026 LiteLLM release v1.107.0 Compromised)。題のとおり、状態は「封じ込めた。調べている途中」("Incident contained, investigation in progress")で、最後の更新は、日本時間の10月22日 5時30分(告知では October 21, 2026 20:30 UTC)です。
告知の中心の文は、こうです。10月21日に、LiteLLM の公開の仕組み(release pipeline)が乗っ取られ、v1.107.0 が Docker の登録所と PyPI に出ました。この版には、資格情報を盗み、外からコードを動かす道具を読み込む仕組みが入っていました。それより前の版は安全で、当たった版は取り下げた、と告知は書いています。
乗っ取りの経緯は、告知の 1 文の範囲で書きます。GitHub にある正式な v1.107.0 のソースには悪いファイルは無く、当たった配布物は、攻撃者が握るリポジトリから作られた、と告知は書いています。企業向けの非公開の版(private enterprise release)を使っている人は、当たっていません。
この件の issue(GitHub の相談・報告の場)を立てたのは、LiteLLM の外の報告者です。LiteLLM の担当者が、そこに状況を書き込んできました。この種の件の全体像は、ソフトウェアのサプライチェーン攻撃とはの記事で説明しています。
当たる時間(日本時間)
告知の時刻(UTC)に 9 時間を足した、日本時間です。すべて 2026年10月21日です。
| 配り場 | 名前 | 悪い版だった時間(日本時間) |
|---|---|---|
| PyPI | litellm==1.107.0 | 20時39分〜22時23分(約 2 時間) |
| Docker Hub | v1.107.0・latest・main-latest・main-stable の 4 つのタグ | 20時46分〜23時20分 |
GHCR(GitHub のイメージの置き場)の 3 つのイメージ(ghcr.io/berriai/litellm・litellm-database・litellm-non_root) | 同じ 4 つのタグ | 20時46分〜22時51分(使えなくなるまで) |
ダイジェストの値はここには写しません。告知に載っています。
たとえ話で見ると
お店の棚に、いつもの商品の箱が並んでいます。ところが、ある夜、いつものメーカーの工場ではない場所で詰められた箱が、正規の配送の仕組みに乗って、棚に並んでしまいました。その箱を買って自分の部屋に置く(入れる)と、箱の中の仕掛けが、その部屋の明かりをつけるたびに動きます。箱を開けなくても、中を確かめようとして明かりをつけても、動きます。仕掛けは、家の合鍵を写して持ち出します。だから、確かめるときは明かりをつけずに、外から名前で探します。合鍵を写されたかもしれないなら、鍵を付け替えます。
例えの物と、実際の物の対応は、次のとおりです。
- お店の棚:PyPI と Docker の登録所
- 工場:GitHub の正式なソース。工場ではない場所:攻撃者が握るリポジトリ
- 正規の配送の仕組み:LiteLLM の公開の仕組み(release pipeline)
- 箱を買って自分の部屋に置く:LiteLLM を入れる・イメージを使う
- その部屋の明かりをつけるたび:その Python を起動するたび
- 箱の中の仕掛け:余分なファイル
- 合鍵を写して持ち出す:資格情報を盗む
告知の言い方では、こうなります。LiteLLM の公開の仕組みが乗っ取られ、GitHub の正式なソースではなく、攻撃者が握るリポジトリで作られた配布物が、PyPI と Docker の登録所に出ました。OSV(オープンソースの脆弱性やマルウェアの記録を集めた公開のデータベース)の記録によると、1.107.0 は余分な 3 つのファイルを持ち、pip はそれを site-packages(Python の部品が入る場所)のすぐ下に入れます。そのため、litellm を import しなくても、その Python を起動するたびに動きます。告知も、当たった環境では、Python を起動するたびに cook.pth と sitecustomize.py がまた動き、pip を動かすのも含む、と書いています。
CVE の番号は付いている?
この件に CVE の番号は、2026年10月23日の17時ごろの時点で見つかりませんでした。CVE は、脆弱性に付く世界共通の管理番号です。
別の記録は付いています。GitHub Advisory Database の、マルウェアの記録(種類は "malware")GHSA-92x9-889m-jgmwに、3月の 1.82.7・1.82.8 と同じ記録に、10月22日の更新で 1.107.0 が載っています。これは LiteLLM が出した告知ではなく、GitHub のデータベースの記録です。OSV にも MAL-2026-2144 があります。
10月23日(日本時間)に NVD(アメリカの脆弱性のデータベース)に出た LiteLLM の CVE-2026-114612 は、別の件です。権限の昇格の脆弱性で、当たる範囲に 1.106.2 は入っていません。番号の読み方は、脆弱性の知らせの読み方にあります。
自分の環境は当たる? 告知の条件で見る
当たるかどうかは、告知の「Who is affected」(誰が当たるか)の文で決めます。原文の訳は、こうです。10月21日の20時39分から22時23分(日本時間。UTC の11時39分から13時23分)に、版を固定せずに pip で LiteLLM を入れた人。または、20時46分から23時20分(UTC の11時46分から14時20分)に、Docker のイメージ v1.107.0・latest・main-latest・main-stable を使った(起動した)人です。
そのうえで告知は、1.107.0 を入れた、またはその時間にイメージを使った(起動した)なら、乗っ取られたものとして扱う、と書いています。1.107.0 の入った環境で Python を起動したなら、その環境も同じ扱いです。
pip で入れた人
「版を固定せずに」とは、litellm とだけ書いて、版を決めずに入れた場合です。pip の文書は、「固定」を、== で決まった版を求めること、と説明しています。litellm>= のように下限だけを書く形は、固定ではありません。
いつ入れたかは、その日の作業の記録(デプロイや環境づくりの時刻、イメージを作った時刻など)で見ます。20時39分から22時23分の間に、版を固定せずに入れた操作があれば、当たります。
CI で入れた人
10月21日の20時39分から22時23分(日本時間)に、LiteLLM を版を固定せずに入れた実行があったかを、CI の実行の一覧の時刻で見ます。Docker のイメージを使う CI は、20時46分から23時20分です。あれば、乗っ取られたものとして扱い、その CI が持つ秘密を替えます。
実行の一覧は、GitHub なら、リポジトリの「Actions」のタブで、左の一覧からワークフローを選ぶと見られます。コマンドの gh run list --json createdAt,startedAt で出した時刻は、UTC の形でした(このブログのリポジトリで、手元で流しました)。UTC なら、pip の時間は11時39分から13時23分、Docker は11時46分から14時20分です。
GitHub が用意する実行環境(GitHub-hosted runner)は、1 CPU のものを除き、ジョブごとに GitHub の新しい仮想マシンだと、GitHub の文書は書いていますが、これは「あとに残らない」という話です。告知は、1.107.0 の入った環境で Python を起動したなら、乗っ取られたものとして扱うと書き、外のネットにつながる機械なら、送り出しは成功したと考えるよう書いています。その実行の中にあった秘密も、告知の「その機械のどのプロセスの環境変数に入っていた秘密も」に当たると読めます。自分で置く実行環境(self-hosted)には、使い捨ての保証はありません。
Docker のイメージを使った人
告知が挙げるのは、v1.107.0・latest・main-latest・main-stable の 4 つのタグを、Docker Hub は20時46分から23時20分、GHCR は20時46分から22時51分の間に、使った(起動した)人です。latest のようなタグは、指す先が付け替えられるので、手元のイメージが悪いものだったかは、ダイジェストで比べます(→「Docker:イメージを起動せず、ダイジェストを告知と比べる」)。
Docker Hub の名前は、告知に書かれていません。手元で見ると、litellm/litellm・litellm/litellm-database・litellm/litellm-non_root がありました。GHCR の名前は告知に書かれています(ghcr.io/berriai/litellm・litellm-database・litellm-non_root)。
LiteLLM の文書の Docker の始め方は、docker.litellm.ai/berriai/litellm:latest という名前を使っています。告知は、この名前を書いていません。確かめ方は、「Docker:イメージを起動せず、ダイジェストを告知と比べる」の節に書きました。
uv など、pip 以外で入れた人
告知の条件は、「pip で」とだけ書いています。uv など別の道具で入れた場合を、告知は書いていません。そのため、この記事は、uv などで入れた人が当たる・当たらないとは言いません。
確かめ方は、同じです。探すファイルの名前は同じです。dist-info の名前の形({名前}-{版}.dist-info)は、Python の部品の置き方の決まり(PyPA の仕様)で決まっていて、ふつうは site-packages に置かれます。uv の使い方は、uv の記事にあります。
uv を使うと、uv のキャッシュ(取ってきた部品の置き場)の中にも、dist-info の名前のフォルダーができました(手元で 1.106.2 を入れて見ました)。ホームから探すと、そこにも出ます。1.107.0 を uv で入れたとき、キャッシュに何が残るかは、確かめていません。
当たらないと告知が書く人
告知は、それより前の版は安全で、企業向けの非公開の版(private enterprise release)は当たっていない、と書いています。OSV の記録も、1.106.2 と 1.107.0rc1・rc2 は当たらない、と書いています。
どうやって確かめる? Python を動かす前にファイルを探す
先に Python を動かさない理由
告知は、当たった環境で Python を起動すると、どの起動でも(pip を動かすのも含めて)、cook.pth と sitecustomize.py がまた動く、と書いています。「pip での導入から始めない」とも書いています。
Python の公式の文書も、同じ向きのことを書いています。site モジュールは、起動のときに自動で読み込まれます。.pth ファイル(Python が起動のときに読むファイル)の中の、import で始まる行は実行され、その部品を使うかどうかに関わらず、Python を起動するたびに動きます。また、起動の途中で sitecustomize という名前のモジュールを読み込もうとします。
だから、疑わしい環境では、確かめるためにも Python を動かしません。ファイルの名前を、外から探します。Python の起動を一部省く方法は、告知に載っていないので、この記事では勧めません。
ここでいう環境は、LiteLLM が入っているかもしれない Python(仮想環境なら、その仮想環境)のことです。作り直すのは環境、鍵を替えるのは、その機械から手の届いたものです。
探す3つのファイル
告知が挙げる 3 つは、次のとおりです。
litellm-1.107.0.dist-info(1.107.0 が入ったことを記録するフォルダー)cook.pthsitecustomize.py(部品の置き場〔site-packages など〕のすぐ下にあるもの)
告知は、1 つ見つかれば当たったと確かめられる、見つからなくても、きれいだという証明にはならない、と書いています。
sitecustomize.py は、Python の起動のときに読み込まれる、ふつうの仕組みのファイルでもあります。見るのは、部品が入る場所(site-packages。Debian・Ubuntu の OS の Python に pip で入れた分は dist-packages)のすぐ下にある …/site-packages/sitecustomize.py です。正規の物は、場所で見分けます。Debian の Python のパッケージでは、/etc/python3.13/ や /usr/lib/python3.13/ にあります(手元の Ubuntu 24.04 では、/etc/python3.12/sitecustomize.py と、それを指す /usr/lib/python3.12/sitecustomize.py)。
Mac・Linux で探す
ファイルの名前を探すだけで、Python は動かしません。手元の Mac で、ホームから流した 1 行は、こうです。
find ~ \( -type d -name 'litellm-*.dist-info' -o -type f -name 'cook.pth' -o -type f -name 'sitecustomize.py' \) -print
~ は、自分のホームのフォルダーです。プロジェクトのフォルダーや仮想環境(プロジェクトごとに部品を分けて入れる箱)のフォルダーなど、ほかの場所を探すときは、~ をその場所に書き換えます。Linux のコンテナで機械全体を探したときは、/ から -xdev を付けて流しました(管理者の権限)。
find / -xdev \( -type d -name 'litellm-*.dist-info' -o -type f -name 'cook.pth' -o -type f -name 'sitecustomize.py' \) -print
条件を -o でつなぐときは、条件全体を \( … \) で囲んでから -print を付けます。囲まずに書くと、-print が一部にしか掛からず、見つかっても表示されないものが出ます(終了コードは 0 のままです)。手元で、正しい形と誤った形を比べて確かめました。
出てきた行の読み方は、次のとおりです。
litellm-1.107.0.dist-info:当たりましたlitellm-の別の版(litellm-1.106.2.dist-infoなど):この件の悪い版ではありませんcook.pth:当たりました- 部品の置き場のすぐ下の
sitecustomize.py:当たりました - それ以外の場所の
sitecustomize.py(OS・Homebrew・エディターの拡張機能などが入れた物):数えません - uv のキャッシュの中の dist-info:「uv など、pip 以外で入れた人」の節を見てください
悪くない 1.106.2 だけが入った作業用の仮想環境で、同じ形で探すと、次の 1 行が出ました。.pth と sitecustomize.py は、ありませんでした。
<仮想環境>/lib/python3.12/site-packages/litellm-1.106.2.dist-info
手元の Mac で、ホームから探したときの結果と、その読み方です(macOS 14)。
- 終わるまで 229 秒かかりました。長くかかることがあります
- 画面に
Operation not permittedが 171 行出ました。macOS が見せない場所(~/Library/の下のContainersなど、写真のライブラリの中)を読めなかった、という表示です。見つかった印ではありません。流したアプリに与えられた権限で、出方は変わりえます findの終了コードは 1 でした。見えない場所があったためで、「見つからなかった」の意味ではありません。見えなかった場所の分は、確かめられていませんsitecustomize.pyは 5 つ出ましたが、どれも部品の置き場のすぐ下ではありませんでした(エディターの拡張機能の Python のデバッガーの中に 3 つ、uv のキャッシュの中のよその部品の試験のファイルに 2 つ)。数えません。litellm-*.dist-infoは 0 でした(この Mac のホームには LiteLLM を入れていません)- Homebrew の Python は、標準ライブラリの場所に、Homebrew が作った
sitecustomize.pyを持っています(部品の置き場の外)
Linux のコンテナで見たことです(Debian 13・Ubuntu 24.04)。
- OS の Python に pip で入れると、
dist-packagesという名前のフォルダー(/usr/local/lib/python3.13/dist-packages/など)に入ることがありました。site-packagesという名前だけで探すと見落とすので、dist-info の名前で探します - 管理者でない利用者で
find /を流すと、管理者の仮想環境(/root/…)の分は出ませんでした。管理者の権限で流すと出ました
Windows で探す
Windows では、この記事で手順を流して確かめていません。コマンドは載せません。場所だけを書きます。site-packages の場所は、Python の文書によると、<Python のフォルダー>\Lib\site-packages です。仮想環境の中にも Lib\site-packages ができます。この中で、上の 3 つの名前を探します。
Docker:イメージを起動せず、ダイジェストを告知と比べる
中を見るために、疑わしいイメージを起動しません。 手元のイメージのダイジェストを、告知の値と比べます。
ダイジェストは、イメージごとに付く識別の文字列で、元が変わらなければ同じ値になります。告知は、当たったイメージのダイジェストを載せていて、そのダイジェストのイメージを動かしたコンテナは、乗っ取られたものとして扱う、と書いています。値はこの記事に写さないので、告知を開いて比べてください。docker.litellm.ai から取った人も、同じ比べ方です。
手元にあるイメージのダイジェストは、次のどちらかで見られます。どちらも、イメージの情報を見るだけです。docker image ls --digests は、タグを付けずに、名前だけで書きます。手元で流した形は、次です(litellm/litellm は、自分が使った名前に書き換えます)。
docker image ls --digests litellm/litellm
docker image inspect --format '{{json .RepoDigests}}' litellm/litellm:v1.106.2
見るのは、docker image ls --digests の DIGEST の列か、RepoDigests の値です。手元で、悪くない litellm/litellm:v1.106.2 を取って比べたところ、docker pull の Digest: の行・DIGEST の列・RepoDigests・Docker Hub の API の値の 4 つは同じでした。docker image inspect の .Id(イメージの ID)は別の値なので、告知のダイジェストとは比べません。
動いているコンテナが、どのイメージから起動されたかは、止めずに見られます。docker ps の IMAGE の列は、起動に使った名前(タグ)を出します。タグは、あとから別のイメージに付け替えられるので、名前だけでは起動したときの中身とは限りません。次の形で、イメージの ID から引きます。
docker inspect --format '{{.Image}}' <コンテナ>
docker image inspect --format '{{json .RepoDigests}}' <出てきたイメージの ID>
この 2 つの流れも、手元で確かめました(悪くない 1.106.2 のイメージで、中の sleep だけを動かしました)。疑わしいイメージでは、この形でも起動しません。Docker の保存の形が containerd の設定の場合は、この出方を確かめていません。
告知の値と同じなら、そのイメージを動かしたコンテナは、乗っ取られたものとして扱います(→「入っていたら、何をする? 告知の手順」)。値が違っても、時間に当たる使い方があったなら、乗っ取られたものとして扱います(→「見つからなかったとき」)。
見つからなかったとき
3 つのファイルが見つからなくても、きれいだという証明にはなりません。告知がそう書いています。10月21日の20時39分から22時23分(Docker は20時46分から23時20分)に当たる操作があったなら、見つからなくても、乗っ取られたものとして扱います。
告知は、当たったかどうかの見つけ方を、もっと詳しく載せると書いていますが、2026年10月23日の時点では載っていません。載ったら、そちらを見てください。
入っていたら、何をする? 告知の手順
次の手順は、告知の "What to do if you are affected"(当たったときにすること)の内容です。LiteLLM の告知は、これを、この件を見つけるのを手伝った報告者の手順だ、と書いています。
先に、ネットの話です。告知は、外のネットにつながる機械に一度でも 1.107.0 を入れたなら、送り出し(盗んだ資格情報を外へ出すこと)は成功したと考えるよう書いています。
- Python を起動しません。 pip を動かすのも、Python の起動です
- シェル(ターミナルで打つコマンド)から、ファイルを消します。 当たった環境の部品の置き場(site-packages)のすぐ下の
cook.pth・cook.py・sitecustomize.pyと、__pycache__の中の対応するcook*.pyc・sitecustomize*.pycを消します。cook.pyも消します。消すのは、見つかった悪い版の環境のものです。OS や Homebrew が入れた正規のsitecustomize.py(部品の置き場の外にあるもの)は、消しません - 裏で動き続ける python のプロセスを止めます。 告知によると、このプロセスは
/tmp/remote_code_loader.lockを使い続けています(ロックしています) - 作り直した環境で、
litellm==1.106.2に固定して入れ直します。 イメージと仮想環境は、一から作り直すほうがよい、と告知は書いています - 鍵を替えます(下の節)
替える鍵(告知が名指しするもの)
告知は、その機械から手の届いたものを全部替えるよう書き、とくに次の 4 つを挙げています。
- インスタンスやタスクの IAM ロール(クラウドの機械に付ける権限)
- LiteLLM のプロキシの DB に入れた、すべての提供元(AI のモデルを出している会社)の鍵と、マスターキー・仮想キー(LiteLLM の文書は、仮想キーを、利用者・チーム・プロジェクトごとに配る鍵と説明しています)
DATABASE_URLのパスワード- その機械の、どのプロセスの環境変数に入っていた秘密も
自分のパソコンで使っていた人は、上の 4 つがサーバー向けの言い方に見えるかもしれません。そのパソコンから手の届いたものを全部替えます。何が盗まれうるかは、OSV の記録の種類も見てください。OSV の記録によると、盗む対象には、次のものが挙がっています。
- ブラウザーのパスワードと履歴
- SSH の鍵・シェルの履歴
- AWS/GCP/Azure の資格情報とクラウドのメタデータ
- Kubernetes・Docker・Vault と CI の秘密
- AI の開発の道具の設定
- GPG と TLS の秘密鍵
.npmrc・.pypirc・.git-credentials- 環境変数
鍵を .env に置いていた人は、.env の記事の考え方が役に立ちます。AI の API キーは、本番の資格情報と同じに扱います(AI を悪用した攻撃の記事に、その考え方があります)。
AWS で動かしていた人
告知は、入れた時刻のあたりに、インスタンスのロールから GetCallerIdentity が呼ばれていないかを CloudTrail(AWS の操作の記録)で見て、そのあと、そのロールの資格情報が自分の設備の外から使われていないかを見る、と書いています。
当たっていなくても:版を固定する
いまの版は 1.106.2(直った新しい版は出ていない)
PyPI は 1.107.0 を隔離し(人が読む画面は "Quarantined")、pip が見る一覧から外しました。いま、pip が見る一覧のいちばん新しい版は 1.106.2 です。直った新しい版は、出ていません。1.107.1 という版は、PyPI にありません(2026年10月23日時点)。GitHub の Releases にも、v1.107.0 はありません。
LiteLLM は、自分たちの配り場を新しい版が出せないように閉じたまま、ふだんの版の公開も止めたままだと、10月22日に書いています。
告知が勧めるのは、次の文です。原文の訳は、「当面は(For the time being)、1.106.2 か、この告知の時点より前に出た版に、番号を決めて固定してください」です。1.106.2 は、告知と OSV の記録のどちらでも、当たらないとされています。
pip で版を固定する
この段のコマンドは、時間と条件に当たらない環境か、作り直した環境で流します。当たったかもしれない環境では、流しません(Python の起動になるためです)。
pip install litellm==1.106.2
pip freeze > requirements.txt
== で決まった版を求めるのが、pip の文書の言う「固定」です。pip freeze も、当たらない環境か作り直した環境で流します。これで、直接入れたものだけでなく、依存(その部品が使う部品)もすべて固定した requirements のファイルが作れます。>= のような下限だけの書き方は、固定ではありません。
pip の文書は、ハッシュ(部品の中身から計算した識別の文字列)も付けて固定すると、PyPI や HTTPS の証明書の連なりが乗っ取られた場合にも守れる、と書いています。今回の件でハッシュが何を防いだかは、この記事では言いません。
Docker はダイジェストで固定する
Docker の文書によると、タグで取ると、取り直すたびに新しい版になりうるのに対し、ダイジェストで取ると、その版に「固定」でき、いつも同じイメージを使えます。
報告者は、10月21日の時点で、タグではなくダイジェストで v1.106.2 に固定するよう勧めています。これは報告者の勧めで、LiteLLM の告知の文ではありません。疑わしいイメージは、ここでも起動しません。
uv で入れている人
uv.lock で版を固定する話は、uv の記事にあります。この記事で、新しいコマンドは足しません。ここでも、時間と条件に当たらない環境か、作り直した環境で行います。
被害と公的機関の告知は?(2026年10月23日時点)
入れた人の数や、被害の件数は、告知にも LiteLLM の担当者の書き込みにも、見つかりませんでした。告知は、外のネットにつながる機械に入れたなら、送り出しは成功したと考えるよう書いています。
公的機関の一覧は、2026年10月23日の16時56分から17時7分ごろ(日本時間)に見た範囲では、次のとおりです。
| 出どころ | 見たこと |
|---|---|
| CISA(アメリカの政府機関)の告知とニュースの一覧 | LiteLLM の 1.107.0 の件はありません。KEV(悪用が確認された脆弱性の一覧)には LiteLLM が 3 件ありますが、どれも前の別の脆弱性です。この件は CVE が無い件です |
| JPCERT/CC(日本のセキュリティの情報を扱う組織)の注意喚起と Weekly Report の一覧 | LiteLLM は載っていません(Weekly Report のいちばん新しいのは10月21日号) |
| IPA(情報処理推進機構)の注意喚起の一覧 | LiteLLM は載っていません |
| LiteLLM のリポジトリの Security Advisory(脆弱性の告知) | この件のものはありません。いちばん新しいのは、10月1日公開の別の件です |
KEV に無いことや、一覧に載っていないことは、被害が無い証明ではありません(脆弱性の知らせの読み方に、同じ読み方を書きました)。
告知は、次の更新を「22:30 UTC」(日本時間の10月22日 7時30分)と書いたまま、20:30 UTC の版のままです。担当者は、issue に、10月22日の11時19分に、2 時間ごとの更新をやめ、大きな進展があったときに書く形に変えた、と書いています。
よくある質問
新しい版に上げればいいですか?
上げる先の版が、ありません。「1.107.1 以上へ」と書いた記事を見かけるかもしれませんが、PyPI に 1.107.1 はありません(2026年10月23日時点)。告知が勧めるのは、「当面は、1.106.2 か、この告知の時点より前に出た版に、番号を決めて固定してください」です(→「当たっていなくても:版を固定する」)。
ほかの記事で、Python のコマンドで版を見る方法を見ました。先にそれをしてもいいですか?
その方法は、告知にも載っています。ただ、同じ告知が、当たった環境では、pip を含めて Python を起動すると、仕組みがまた動く、とも書いています。Python の文書も、.pth の import の行は、起動のたびに動くと書いています。当たった可能性のある環境では、先にファイルを探します(→「どうやって確かめる? Python を動かす前にファイルを探す」)。
LiteLLM を自分で入れた覚えがありません。関係ありますか?
関係あることがあります。自分で入れていなくても、ほかの部品の依存として入ることがあります。pip の文書は、requirements のファイルの固定が、直接入れたものだけでなく、依存の依存(transitive dependencies)にも及ぶ、と書いています。探し方は同じです。dist-info の名前を探します(→「探す3つのファイル」)。
LiteLLM の文書にある docker.litellm.ai のイメージを使っていました。当たりますか?
LiteLLM の文書の Docker の始め方は、この名前を使っています。告知は、この名前を書いていません。悪いイメージが出ていた時間に、この名前で悪いイメージが配られたかは、確かめられませんでした。いまは、GHCR と同じものを返します(手元で確かめました)。当たる・当たらないを決めず、イメージを起動せずに、ダイジェストを告知の値と比べてください(→「Docker:イメージを起動せず、ダイジェストを告知と比べる」)。
1.106.2 より古い版に固定してもいいですか?
この記事では言えません。告知は、それより前の版は安全と書いています。一方、3月の 1.82.7・1.82.8 は、GitHub のデータベースと OSV に悪い版として載っています(いま PyPI にありません)。古い版には、別の脆弱性もあります(KEV には LiteLLM の別の件が 3 件あります)。告知が名指しするのは、1.106.2 です(→「いまの版は 1.106.2(直った新しい版は出ていない)」)。
- 10月21日の20時39分〜22時23分(日本時間)に、版を固定せずに LiteLLM を入れた操作があったか、記録の時刻で見る(→「pip で入れた人」)
- CI は、実行の一覧の時刻で見る(Docker のイメージを使う CI は20時46分〜23時20分)(→「CI で入れた人」)
- Docker は、
v1.107.0・latest・main-latest・main-stableを、20時46分〜23時20分に使ったか見る(→「Docker のイメージを使った人」) - 疑わしい環境では Python を動かさず、
litellm-1.107.0.dist-info・cook.pth・部品の置き場(site-packages など)のすぐ下のsitecustomize.pyを探す(→「探す3つのファイル」「Mac・Linux で探す」) - Docker は、イメージを起動せず、ダイジェストを告知の値と比べる(→「Docker:イメージを起動せず、ダイジェストを告知と比べる」)
- 当たったなら、告知の手順で消し、作り直し、鍵を替える(→「入っていたら、何をする? 告知の手順」「替える鍵(告知が名指しするもの)」)
- LiteLLM を使い続けるなら、当たっていなくても、当たらない環境か作り直した環境で、
litellm==1.106.2に固定する(→「当たっていなくても:版を固定する」)
まとめ
- 2026年10月21日、LiteLLM 1.107.0 に、資格情報を盗む仕組みが入って、PyPI と Docker の登録所に配られた。ソフトの弱点ではなく、悪い版そのものが配られた件。CVE の番号は付いていない(2026年10月23日時点)
- 当たるのは、10月21日の20時39分〜22時23分(日本時間)に版を固定せずに pip で入れた人と、20時46分〜23時20分に 4 つのタグのイメージを使った人。それより前の版は安全と告知は書く
- 確かめるときは、疑わしい環境で Python を動かさない。ファイルの上で、告知の 3 つを探す。Docker はイメージを起動せず、ダイジェストを告知の値と比べる
- 入っていたら、乗っ取られたものとして扱う。告知の手順でファイルを消し、環境を作り直し、その機械から届く鍵を全部替える
- LiteLLM を使い続けるなら、当たっていなくても、当たらない環境か作り直した環境で、1.106.2 に固定する。直った新しい版は出ていない
- 公的機関(CISA・JPCERT/CC・IPA)の一覧に、この件は見つからなかった。ただし、載っていないことは、被害が無い証明ではない
- この記事で確かめていないこと:
docker.litellm.aiで、悪いイメージが出ていた時間の中身- uv や Poetry で入れた人が当たるか
- Docker のイメージの中に
litellm-1.107.0.dist-infoがあるか - pip や uv のキャッシュに 1.107.0 が残ったときのこと
- Ubuntu のパッケージの一覧での
sitecustomize.pyの場所(手元の Ubuntu 24.04 で見た 1 つだけ) - Windows での動き、conda の Python、containerd の保存の形の Docker
- 入れた人の数、1.106.2 より古い版の安全さ
参考資料
この記事の内容は、冒頭に書いた日時に開いた文書をもとにしています。告知や公的機関の一覧は、更新されることがあります。
- LiteLLM: 告知(Contained: Oct 21, 2026 LiteLLM release v1.107.0 Compromised)
- GitHub: LiteLLM の issue #47826
- LiteLLM: 文書(Getting Started)・LiteLLM: プロキシ(AI Gateway)・GitHub: BerriAI/litellm
- PyPI: litellm のプロジェクト・litellm 1.107.0 の画面
- Docker のイメージ: Docker Hub: litellm/litellm のタグ・GHCR(litellm・litellm-database・litellm-non_root)・GitHub: Releases の v1.106.2
- 番号の記録: GitHub Advisory Database: GHSA-92x9-889m-jgmw・OSV: MAL-2026-2144・OSV: PYSEC-2026-2
- LiteLLM: Security Advisories
- 公的機関: CISA: 告知の一覧・CISA: KEV の一覧・JPCERT/CC: 注意喚起の一覧(2026年)・JPCERT/CC: Weekly Report(2026年)・IPA: セキュリティ注意喚起(2026年)
- Python: site モジュール(Python 3.13)・site モジュール(最新)・venv・PyPA: 入れたものの記録(dist-info)・pip: 繰り返し同じ環境を作る
- Debian: libpython3.13-minimal のファイル一覧
- Docker: docker image ls・docker image pull・docker inspect・docker container ls
- GitHub: ホストされたランナー・安全な使い方・実行の履歴を見る
※この記事は、2026年10月23日時点の公式の資料と照らして確かめています。誤りに気づいたらお問い合わせからお知らせください。



