はじめに
僕らの世界が何者かに侵略されてるぞ nikkieです1。
PyPI に最新版として公開された悪意あるパッケージをインストールしない方法にはどんなものがあるか調べました。
目次
ひっくり返った前提:PyPI からの最新版インストールは、リスク
TeamPCP により(Trivy への攻撃から)LiteLLM が攻撃されました。
悪意あるパッケージが PyPI に公開され、私も被害を被りました(以下の記事で対応はしています)
攻撃は現在も続いています。
😼New TeamPCP: PyPI package "telnyx" versions 4.87.1 and 4.87.2 contain malware.
— Rami McCarthy (@ramimacisabird) 2026年3月27日
These versions were uploaded directly to PyPI (no matching GitHub tags/releases). Downgrade to 4.87.0 or earlier immediately.
Windows payload appears broken in 4.87.1.
世界は大きく変わってしまいました。
PyPI から最新のパッケージのインストールには、これまでよりもリスクが伴います。
ツールに仮想環境を任せる(uvxや inline script metadata)のが好きな私としては、最新のパッケージをインストールする選択肢は持っておきたく、対抗する術を探しました。
インストーラで対策
cooldown と呼ばれるみたいです。
我が師 simonw 氏による一覧
uv
uvには--exclude-newerオプションがあります。
https://docs.astral.sh/uv/concepts/resolution/#dependency-cooldowns
uv also supports dependency "cooldowns" in which resolution will ignore packages newer than a duration.
Define a dependency cooldown by specifying a duration instead of an absolute value.
24 hours, 1 week, 30 daysのように指定できます。
uvx2でも効きますね。
https://docs.astral.sh/uv/reference/cli/#uv-tool-run--exclude-newer
環境変数UV_EXCLUDE_NEWERでも指定できます。
uvの設定ファイルでも指定できます。
user レベルと system レベルの2段階があります。
https://docs.astral.sh/uv/reference/storage/#configuration-directories
user レベルの例は$HOME/.config/uv(OS にもよるので詳しくはドキュメント参照ください)
exclude-newerの書き方
https://docs.astral.sh/uv/reference/settings/#exclude-newer
pip
先日リリースされた 26.0 で--uploaded-prior-toオプションが入っています。
https://ichard26.github.io/blog/2026/01/whats-new-in-pip-26.0/#excluding-distributions-by-upload-time
The new --uploaded-prior-to option allows you to filter packages by their upload time to a package index, only considering packages that were uploaded before a specified datetime.
https://pip.pypa.io/en/stable/user_guide/#filtering-by-upload-time
python -m pip install --uploaded-prior-to=2025-03-16T00:00:00Z SomePackage
※24 hoursのような指定はできません
環境変数PIP_UPLOADED_PRIOR_TOでも指定できます。
https://pip.pypa.io/en/stable/cli/pip_install/#cmdoption-uploaded-prior-to
また、pipの設定ファイルでも指定できます。
https://pip.pypa.io/en/stable/topics/configuration/#config-file
3レベルあるうちの1つ$HOME/.config/pip/pip.conf(OS にもよるので詳しくはドキュメント参照ください)
パッケージインデックスで対策
画像の1行コマンドでマルウェアPythonパッケージをブロックできます(無料・登録不要)
— pizzacat83 (@pizzacat83b) 2026年3月25日
様々なOSSの侵害が連鎖しているので、ぜひ活用して自衛ください🙏
Flattで全ての新規パッケージを検査しブロックしています。72時間の検疫期間も設けており、minimumReleaseAge相当の対策にもなります。 https://t.co/EH2km7ryug
(Astral は pyx でも対策できる余地ありますね。何か考えてるのかな?)
終わりに
LiteLLM への攻撃以降、PyPI からインストールする最新パッケージは悪意あるものかもしれないというリスクが私はもう無視できません。
インストーラの cooldown の設定方法、また、パッケージインデックスでの対策を知りました。
Python のインストーラでは cooldown がない期間の方が長かったので、間に合ってよかったという安堵が大きいです。
cooldown を設定して、リスクを低減していきましょう!
最後に、私は TeamPCP を最も強い言葉で非難します。