10年前の2016年、当時同じチームにいた後輩が「あなたのサーバは本当に安全ですか?」という記事を書いた。Vuls の紹介記事だ。
海外ではすでに Vuls がバズり始めていたが、日本ではまだ知られていなかった。ちょうど国内でも広めようとしていた矢先に、後輩が自ら進んで書いてくれたのだ。サーバに潜む既知の脆弱性——パッチを当てていれば防げたはずのリスクを可視化するツールとして、多くの反響をいただいた。
あれから10年。問いの形は変わっていないが、対象が変わった。
「あなたのサーバは本当に安全ですか?」から、「あなたのプロジェクトの依存関係は本当に安全ですか?」へ。
CIパイプラインに SCA(Software Composition Analysis:依存ライブラリの脆弱性を自動検出するツール群)を組み込み、検出された CVE(公開された脆弱性の識別番号)を修正し、ビルドがグリーンになった。これで安全だ——そう思っていないだろうか。
SCAツールは優秀だ。既知の脆弱性を確実に見つけてくれる。だが、それでも見えないものがある。
試しに OWASP Juice Shop(セキュリティ学習用の有名なサンプルアプリ)を Trivy でスキャンすると、293 件の脆弱性が検出される。SCA は仕事をしている。
では、その 1,540 件の依存パッケージ(自分が直接使うライブラリだけでなく、その先の依存——推移的依存——を含む)をライフサイクル(開発の活発さやメンテナンス状態)の観点で分析するとどうなるか。
活発にメンテナンスされている(Active)のは40.9%だけだ。残りの 59% は、開発が止まっているが安定して使えるもの(Legacy-Safe)が 36.1%、メンテナンスが衰退しつつあるもの(Stalled)が 17.1%、事実上の EOL が 5.9% という内訳だった。これらのライフサイクル上の懸念は、SCAでは検出できない。
具体例を挙げよう。
gorilla/mux(GitHub スター 22K)は Go の Web ルーターとして長年の定番だった。しかし 646 日間、実質的なメンテナンス活動が止まっていた時期がある。スター数は信頼の証明にならない。
passport(GitHub スター 24K)は Node.js の認証ライブラリとして広く使われている。OpenSSF Scorecard のスコアは 2.8(10 点満点)、最終コミットから 588 日が経過していた。
create-react-app(GitHub スター 104K)は Facebook が公式に提供していた React のプロジェクト生成ツールだ。しかし 406 日以上メンテナンスが止まり、事実上の放棄状態となった。スター数 10 万超のプロジェクトでさえ、突然死ぬ。
これらのパッケージには、少なくともスキャン時点で深刻な CVE は登録されていなかった。どの SCA ツールも「問題なし」と言う。だが本当に問題はないのだろうか。
これは教育用サンプルアプリに限った話ではない。我々が国内企業の実稼働環境にある約 16,000 件の OSS を独自分析したところ、本番運用されている OSS の約 50% が開発停滞・実質的 EOL・公式 EOL のいずれかに該当するという結果が出ている(詳細は『ソフトウェアサプライチェーン健全性レポート 2026』にまとめた)。
OS や商用ソフトウェアの世界では、EOL(End of Life)の管理は比較的整備されている。Ubuntu 22.04 LTS のサポートが 2027 年 4 月まで、Red Hat Enterprise Linux 8 が 2029 年まで——ベンダーが公式に期限を発表し、企業の IT 部門はそれをもとに計画を立てられる。
ところが OSS には、そういったカタログが存在しない。
世界には 推定 6.3 億を超える OSS パッケージが存在するが、その EOL を体系的に追跡するカタログはない。endoflife.date というコミュニティプロジェクトが存在するが、登録は手動であり 2026 年 4 月時点で 447 件にとどまる。6.3 億超のパッケージに対してカバレッジには限界がある。
現在主流の SCA ツール——Vuls、Trivy、Snyk、Grype——は CVE データベースと照合して既知の脆弱性を検出することを主目的としている。SBOM(Software Bill of Materials:ソフトウェアの部品表)生成ツールの Syft も含め、これらのエコシステムは脆弱性の発見に特化している。我々が開発する Vuls も例外ではない。これ自体は非常に重要な機能だ。ただし、「そのパッケージが今もメンテナンスされているか」という問いには、どのツールも答えてくれない。
OpenSSF Scorecard は、GitHub リポジトリのセキュリティプラクティスを自動で評価するオープンソースツールだ。コード署名、ブランチ保護、依存関係管理など多角的に 10 点満点でスコアリングしてくれる点で優れているが、メンテナンス状態については単一の数値スコアに集約されるため、「いつから止まっているか」「どの程度の活動があるか」といった粒度の情報は得られない。
ここに補完関係がある。SCA ツールが「依存先に何の脆弱性があるか」を教えてくれるとすれば、uzomuzo は「その依存先がメンテナンスされているか」を教える。 両者を組み合わせて初めて、依存関係の全体像が見えてくる。
「メンテされていない OSS を使い続けるリスク」と聞いて、多くの人は「セキュリティアップデートが来ない」程度に捉えるかもしれない。しかしリスクの本質はもう少し深い。
健全な OSS で深刻な脆弱性が発見されたとき、何が起きるか。脆弱性が報告される → メンテナがパッチをリリースする → 利用者は go get -u や npm update を実行する。それだけだ。コストは小さい。
不健全な OSS で同じことが起きたとき、何が起きるか。脆弱性が報告される → 誰も対応しない → フォークして自分たちで修正するか、別のライブラリへ移行するかを迫られる。
この差は計り知れない。フォークを維持するコストは継続的に発生し、移行は既存コードへの大規模な変更を伴う。しかも「脆弱性が発見されたとき」というタイミングは、往々にして最もチームが忙しい瞬間に重なる。
この問題は業界でも認識されつつある。日本経済新聞電子版でも我々のコメントとともに OSS サプライチェーンリスクとして取り上げられ、セキュリティカンファレンス VulnCon 2026 では我々自身がこのテーマで CFP を通し、登壇する。
そしてまさにこの記事を書いている最中、Trivy へのサプライチェーン攻撃が発生した。2026 年 2 月末の初回攻撃では自律型 AI ボットが GitHub Actions の脆弱性を悪用してリポジトリを乗っ取り、全リリースを削除した。3 月 19 日の第 2 波では窃取済みクレデンシャルを再利用し、悪意あるリリースの作成、GitHub Actions・Docker Hub・npm・PyPI への波及、さらに "CanisterWorm" と呼ばれる自己増殖型ワームによる npm パッケージ 66 件以上の汚染にまで発展した(詳細は FutureVuls Blog の第 1 報、第 2 報、影響確認ガイドを参照)。「使っているだけで被害者になる」という OSS の性質が、改めて問い直されているのだ。
「uzomuzo」を作るきっかけになったのは、我々のプロダクト FutureVuls の依存関係ダイエットプロジェクト「vuls-diet」だった。
FutureVuls は脆弱性管理のSaaSで、Scanner に Trivy を内包している。Trivy の作者「knqyf263」との出会いは Vuls のGitHubだった。当時別の会社にいた彼が、Vuls に何度も質の高いPRを送ってきた。
コードを見て「只者ではない」と感じ、ビールに誘って意気投合し、フューチャーで一緒に Vuls を開発する仲間になった。一緒に HITCON で登壇し、セキュリティキャンプの講師も務めた。
その後彼はTrivyを生み出した。そうした信頼関係もあって FutureVuls の ScannerにTrivyを採用した。OSSのSCAツールとして極めて優秀であり、その判断は今も正しかったと思っている。
採用した当時の Trivy はまだシンプルだった。しかし時が経つにつれ、IaC スキャンをはじめとする多くの機能が追加され、Trivy 自体が巨大なプロジェクトへと成長していった。優秀なツールが進化するほど、それに伴う依存ツリーも膨らんでいく。
結果、Scanner のコンパイル済みバイナリは 106.6MB に膨れ上がり、go.mod には 391 の依存が並び、Dependabot(GitHub が提供する依存関係の自動更新サービス)のバージョンバンプ PR が年間数百件発生した。
ロックファイルのパーサだけ使いたいのに、FutureVuls の Scanner では使わない IaC スキャン機能に必要な 254 パッケージまで芋づる式についてくる。これは Trivy の問題ではない。巨大な OSS ライブラリを丸ごと取り込むという判断の問題だ。
この依存を整理しようとして、3 ラウンドの分析を経た。
go mod why -m で実際の依存グラフを検証したところ、想定していた 12 モジュール全てが別の経路でも使われていることが判明した。削減見込みは 45 件から 3〜4 件(約 1%)に激減。想像していた「いらない依存をサクッと外す」は幻想だった。最終的には 2 日間で 8 本の PR を作成した。その過程で印象的なエピソードがある。golang.org/x/xerrors を標準ライブラリの errors パッケージへ置換する作業では、コードベース全体で 788 箇所の変更が必要になった。AI コーディングエージェントを活用して分析・置換・テスト・PR 作成を自動化したのだが、その過程で潜在的なバグが 1 件発見された。依存関係の整理が、思わぬコード品質向上につながったのだ。
さらに根本対策として、Trivy の fanal フレームワーク(各エコシステムのパーサや SBOM 生成を束ねる内部基盤)ごと除去しパーサを直接呼び出す大規模リファクタリングを実施した。Scanner バイナリは 106.6MB → 34.1MB(-68%)、Trivy 由来の依存は 352 → 144(-59%)にまで削減できた。
ただし、この 1 本の PR を通すために 129 件のロックファイルでリグレッションテストを回し、16 エコシステムのパーサ出力が壊れていないことを 1 つずつ検証する必要があった。依存を 1 つ剥がすたびに、こうした地道な検証コストが積み上がる。
OSS は入れるときは go get 一発。外すときは地獄。この非対称性こそが問題の本質だ。
この経験が確信を与えた。「外す苦労を知ったからこそ、入れる前に評価する仕組みが必要だ」 と。
名前の由来から話そう。 uzomuzo は「有象無象(uzōmuzō)」から来ている。雑多な存在、取るに足らないものの集まり、という意味だ。直接依存という「見えるもの」の裏に無数に潜む「見えないもの」——推移的依存——をすべて評価する、という思想をこの名に込めた。
なお、リポジトリ名が uzomuzo-oss なのは、愛知県に同名のラーメン屋「うぞうむぞう」が存在するためだ。食べログ 3.49 の高得点を叩き出している名店だ。まだ食べたことはないが、いつか巡礼しようと思っている。リスペクトを込めて -oss を付けた。
uzomuzo の核心は 7 段階ライフサイクル分類 だ。
| ステータス | 意味 |
|---|---|
| Active | 活発にメンテナンスされている |
| Legacy-Safe | 枯れているが安定して使える |
| Stalled | メンテナンスが止まりかけている |
| EOL-Confirmed | 公式に EOL が宣言されている |
| EOL-Effective | 事実上の EOL 状態 |
| EOL-Scheduled | EOL 予定が公表されている |
| Review Needed | 判定が難しく要確認 |
「メンテされているか否か」の二値ではなく、グラデーションで判断できる。
判定には複数のシグナルを組み合わせる。OpenSSF Scorecard のスコア、コミット活動の頻度と質、リリース頻度、Registry の EOL フラグ、Advisory 件数——これらを統合して分類を決定する。GitHub トークンを設定した場合、コミット履歴から Dependabot や Renovate などのボットコミットを自動的に除外する。
この Bot 分離は独立した機能ではなく、全ライフサイクル判定の基盤ロジックだ。ボットだけが動いているリポジトリを「Active」と誤判定しないために不可欠な仕組みであり、OWASP Juice Shop の分析では 551 件の Legacy-Safe 判定がこの「人間のコミットが 2 年以上ない」という基準に依拠している。5,000 件以上のパッケージをバッチ処理で一気に評価できる点も、実務での利用を想定した設計だ。
導入のハードルも低い。GitHub トークンなしでも deps.dev(Google が運営する OSS パッケージの公開データベース)経由でパッケージメタデータ、Advisory(脆弱性の勧告情報)、OpenSSF Scorecard の全 17 チェックを取得して分析できる。トークンを設定すれば、さらにコミット履歴の人間/Bot 分離やリポジトリの archived/disabled 状態を加味した高精度な判定に切り替わる、という段階的な設計にしている。
既存ツールとの比較をまとめると以下のようになる。
| 観点 | SCA ツール全般 | OpenSSF Scorecard | endoflife.date | uzomuzo |
|---|---|---|---|---|
| 依存先の CVE 検出 | ○ | × | × | △(Advisory 数) |
| 依存先のメンテ状態分析 | × | △(Maintainedのみ) | × | ◎(7 段階) |
| 依存先の Bot コミット分離 | × | × | × | ◎(全判定に内包) |
| 依存先の EOL 検出 | × | × | ○(手動登録) | ◎(自動検出) |
| バッチ処理 | ○ | △ | × | ○(5,000+ 件 / 回) |
uzomuzo は SCA ツールの代替ではない。補完するツールだ。実際、Trivy や Syft が生成した SBOM をワンライナーでそのまま渡せる。
trivy image --format cyclonedx my-app:latest | uzomuzo audit --sbom -
例えば冒頭で紹介した OWASP Juice Shop を評価すると、こんな出力が得られる。
🏷️ LABEL SUMMARY (1,540 evaluated packages):
🟢 Active: 630 (40.9%)
🔵 Legacy-Safe: 556 (36.1%)
⚪ Stalled: 263 (17.1%)
🔴 EOL-Confirmed: 88 (5.7%)
🛑 EOL-Effective: 3 (0.2%)
Trivy はこのイメージから 293 件の脆弱性を検出する。だが uzomuzo が EOL と判定した 91 件のうち、Trivy が脆弱性を検出できたのはわずか 6 件だ。残りの 85 件は Trivy が「0 vulnerabilities」と報告する——SCA の盲点そのものだ。
詳細は GitHub リポジトリ(future-architect/uzomuzo-oss)を参照してほしい。
CVE スキャンは必要だ。続けてほしい。ただそれだけでは、依存関係の健全性の半分しか見えていない。
「脆弱性ゼロ=安全」ではない。メンテされていない依存関係という見えないリスクが、今日もあなたのプロジェクトに潜んでいる。
「見えたところで、どうすればいいのか」——当然の疑問だと思う。1,540 件中 59% に懸念があると言われても、全部を今すぐ直すリソースはない。SCA のアラート疲れに加えて、新しいノイズが増えるだけではないか、と。
答えは「全部直す必要はない」だ。uzomuzo の 7 段階分類は、まさにそのトリアージのために設計した。EOL-Confirmed と EOL-Effective を最優先で対処し、Legacy-Safe は受容する。Stalled は監視リストに入れて次のリリースで判断する。全件をフラットに並べるのではなく、アクションの優先順位を決めるための分類だ。
次の記事では、uzomuzo の実際の使い方を紹介する。SCA ツールが生成した SBOM をそのまま uzomuzo に渡すワンライナーから始め、結果の読み方、トリアージの実践方法まで順を追って説明する予定だ。
uzomuzo は future-architect/uzomuzo-oss として GitHub で公開している。まずスター数の多い「信頼しているつもりの」依存関係を一度評価してみてほしい。その結果に、きっと驚くと思う。
国内企業の OSS、約 50% がゾンビ化——データが示す現実
本記事で触れた「見えない EOL リスク」について、FutureVuls では国内企業の実運用データ約 16,000 件を独自分析したホワイトペーパーを公開している。実質的 EOL と開発停滞の複合リスク、法的負債に変わる前に取るべきプロアクティブな対策についてまとめた。
『ソフトウェアサプライチェーン健全性レポート 2026』を読む