CUBE SUGAR CONTAINER

技術系のこと書きます。

Python: uv audit で脆弱性のある依存パッケージを見つける

Python でソフトウェアを開発するメリットのひとつは、パッケージのエコシステムが発達していることだろう。 自分でゼロから機能を実装する代わりに、PyPI などで公開されている多種多様なパッケージが利用できる。

一方で、ソフトウェアが依存しているパッケージに脆弱性が見つかることもある。 見つかった脆弱性の性質によっては、ソフトウェアを利用するシステムの侵害につながりかねない。 近年は新たに発見される脆弱性が増加し続けており 1、脆弱性が発見されてから悪用に至るまでの期間も短くなっている 2

ソフトウェアが依存しているパッケージの既知の脆弱性に対処するには、まず脆弱性が見つかったことに気づく必要がある。 パッケージマネージャに pip を使っている場合には PyPA がメンテナンスしている pip-audit を使うのが定石のひとつだった。 ただ、pip-audit はパッケージマネージャに uv を使っているプロジェクトとの相性がそこまで良くない。

そんな折、uv のバージョン 0.10.12 から uv audit の機能がプレビュー版として追加された。 これにより、uv を使ったプロジェクトで脆弱性のある依存ハッケージを見つけやすくなった。 今回は、追加された uv audit の機能を紹介する。

docs.astral.sh

使った環境は次のとおり。

$ sw_vers
ProductName:        macOS
ProductVersion:     26.5
BuildVersion:       25F71
$ uv --version               
uv 0.11.16 (Homebrew 2026-05-21 aarch64-apple-darwin)

もくじ

下準備

下準備として、あらかじめ uv をインストールしておく。

$ brew install uv

そして、適当なディレクトリで uv を使ったプロジェクトを初期化する。

$ uv init --name helloworld --vcs none --bare .

これで pyproject.toml ができる。

$ cat pyproject.toml 
[project]
name = "helloworld"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = []

uv audit コマンド

プロジェクトが依存しているパッケージから脆弱性を見つけるには uv audit コマンドを実行する。 この時点ではプロジェクトに依存パッケージが何もないので脆弱性は見つからない。

$ uv audit                                     
warning: `uv audit` is experimental and may change without warning. Pass `--preview-features audit` to disable this warning.
Resolved 1 package in 21ms
Found no known vulnerabilities and no adverse project statuses in 0 packages

なお、この記事を書いている時点で uv audit は実験的な機能という位置づけになっている。 そのため、実行するとその旨の警告が表示される。

警告を表示したくないときは --preview-features audit オプションをつけて実行しよう。

$ uv audit --preview-features audit
Resolved 1 package in 3ms
Found no known vulnerabilities and no adverse project statuses in 0 packages

脆弱性が見つからなかったときにはコマンドの返り値はゼロになる。

$ echo $?                          
0

脆弱性のあるパッケージを依存関係に追加する

では、次に脆弱性のあるパッケージを依存関係に追加してみよう。 試しに requests のバージョン 2.33 未満を依存関係に追加する。

$ uv add "requests<2.33"

バージョン 2.33 未満の requests には CVE-2026-25645 が見つかっている。

これで pyproject.toml に依存パッケージが追加された。

$ cat pyproject.toml
[project]
name = "helloworld"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
    "requests<2.33",
]
$ uv tree                           
Resolved 6 packages in 3ms
helloworld v0.1.0
└── requests v2.32.5
    ├── certifi v2026.4.22
    ├── charset-normalizer v3.4.7
    ├── idna v3.15
    └── urllib3 v2.7.0

この状態で uv audit コマンドを実行してみよう。

$ uv audit --preview-features audit
Resolved 6 packages in 3ms
Found 1 known vulnerability and no adverse project statuses in 5 packages

Vulnerabilities:

requests 2.32.5 has 1 known vulnerability:

- GHSA-gc5v-m9x4-r6x2: Requests has Insecure Temp File Reuse in its extract_zipped_paths() utility function

  Fixed in: 2.33.0

  Advisory information: https://nvd.nist.gov/vuln/detail/CVE-2026-25645

すると、依存パッケージの requests 2.32.5 に脆弱性が見つかっている旨の表示がされる。

コマンドの返り値も非ゼロになる。

$ echo $?                                                                
1

依存パッケージのバージョンを更新する

次は依存パッケージのバージョンを脆弱性が解決されたバージョンに更新してみよう。

今回はパッケージを追加する時点で、バージョンの制約を <2.33 と指定してしまっている。 そこで、更新する場合には改めてより新しいバージョンに依存するよう指定し直す必要がある。

$ uv add "requests>=2.33" --exclude-newer "1 week"

また、昨今のサプライチェーン攻撃のリスクを軽減したいときは --exclude-newer でクールダウン期間を設ける。

これで requests のバージョンが 2.33 以降に更新された。

$ uv tree
Resolved 6 packages in 3ms
helloworld v0.1.0
└── requests v2.34.2
    ├── certifi v2026.4.22
    ├── charset-normalizer v3.4.7
    ├── idna v3.15
    └── urllib3 v2.7.0

もし、バージョン制約がない状態であれば uv lock コマンドを使ってバージョンの Pinning を更新できる。

$ uv lock --upgrade-package requests --exclude-newer "1week"

あるいは、依存しているパッケージを一括で更新する場合には次のようにしても良い。

$ uv lock --upgrade --exclude-newer "1week"

バージョンを更新した上で、改めて uv audit コマンドを実行する。

$ uv audit --preview-features audit               
Resolved 6 packages in 3ms
Found no known vulnerabilities and no adverse project statuses in 5 packages
$ echo $?
0

バージョンを更新したことで、先ほどまで表示されていた脆弱性が表示されなくなった。

開発用の依存関係に脆弱性のあるパッケージを追加する

次は開発用グループに脆弱性のあるパッケージを追加して発見できるか試してみよう。 開発用グループは、ソフトウェアの動作時には不要だが開発時には利用したいパッケージを追加する。

一旦、先ほど追加した requests は依存関係から削除する。

$ uv remove requests

その上で、開発用グループ (dev) に urllib3 のバージョン 2.7 未満を追加する。 開発用グループに依存パッケージを追加するときは --dev--group dev オプションを使用する。

$ uv add --dev "urllib3<2.7"

これで開発用グループに脆弱性のあるパッケージが追加された。 urllib3 のバージョン 2.7 未満には CVE-2026-44431CVE-2026-44432 が見つかっている。

$ cat pyproject.toml
[project]
name = "helloworld"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = []

[dependency-groups]
dev = [
    "urllib3<2.7",
]

この状態で uv audit を実行してみよう。

$ uv audit --preview-features audit
Resolved 2 packages in 3ms
Found 4 known vulnerabilities and no adverse project statuses in 1 package

Vulnerabilities:

urllib3 2.6.3 has 4 known vulnerabilities:

- PYSEC-2026-142: No summary provided

  Fixed in: 2.7.0

  Advisory information: https://github.com/urllib3/urllib3/security/advisories/GHSA-mf9v-mfxr-j63j

- PYSEC-2026-141: No summary provided

  Fixed in: 2.7.0

  Advisory information: https://github.com/urllib3/urllib3/security/advisories/GHSA-qccp-gfcp-xxvc

- GHSA-mf9v-mfxr-j63j: urllib3: Decompression-bomb safeguards bypassed in parts of the streaming API

  Fixed in: 2.7.0

  Advisory information: https://nvd.nist.gov/vuln/detail/CVE-2026-44432

- GHSA-qccp-gfcp-xxvc: urllib3: Sensitive headers forwarded across origins in proxied low-level redirects

  Fixed in: 2.7.0

  Advisory information: https://nvd.nist.gov/vuln/detail/CVE-2026-44431

ちゃんと既知の脆弱性の情報が表示された。

まとめ

今回は uv のプロジェクトで依存しているパッケージに既知の脆弱性があるか調べる機能を紹介した。