再現ビルドだけでは不十分|npm検証52.9%

再現ビルドだけでは不十分|npm検証52.9% 研究・論文

【更新 2026-08-24】本記事を見直し、修正しました。主な修正点:論文の「検証成功率」と「パイプライン完走率」が別々の集計(前者はプロヴェナンスを使わないソース復元時の値、後者はプロヴェナンス付きを含むサンプル全体の値)であることを明記し、npmの完走率の説明を補正。IPA「中小企業の情報セキュリティ対策ガイドライン」のリンク先を、ハブページからガイドライン本体のページに差し替え。

結論から。ソフトウェアの「再現可能ビルド(Reproducible Builds)」は、サプライチェーン攻撃を検知する切り札として期待されてきました。しかし2026年8月18日にarXivで公開された査読前の研究は、再現可能なだけでは足りず、公開情報だけを頼りに第三者が成果物を検証できたのは、npmで52.9%、PyPIで64.6%にとどまったと報告しています。

つまり、自社の業務アプリやアプライアンスに組み込まれているOSSパッケージの多くは、「配布されているバイナリが、公開されているソースコードから作られた」という当たり前の事実を、今の仕組みでは第三者が確かめられない状態にあります。

この記事でわかること

  • 「再現可能ビルド」と「検証可能性」がどう違うのか(この研究の核心)
  • npm / PyPI / crates.io / RubyGems の4大エコシステムで、検証がどれだけ通るのか(実測値)
  • 検証が失敗する具体的な原因トップ3
  • GitHub Actionsの署名(プロヴェナンス)を付ければ解決するのか
  • 情シスとして、この研究結果を調達・資産管理にどう効かせるか

「パッケージエコシステム」とは何者か——うちは関係ない、とは言えない理由

パッケージエコシステムとは、開発者が書いたプログラム部品(ライブラリ)を登録・配布するための公開レジストリと、その周辺の仕組みの総称です。今回の対象は、npm(JavaScript用。Webアプリや社内システムのフロントエンド、Node.js製サーバ)、PyPI(Python用。データ分析・自動化・AI基盤)、crates.io(Rust用。ネットワーク機器やセキュリティ製品の内部実装で採用増)、RubyGems(Ruby用。Rails製の業務Webシステム)の4つです。

情シス部門が自分でnpmやPyPIからパッケージを取得することは、まずないでしょう。しかしこれらのパッケージは、社内で使っている業務パッケージソフト、SaaS、ネットワーク機器のファームウェア、複合機の管理画面の「中に」組み込まれて動いています。資産管理台帳には「○○システム」としか載っていなくても、その内側には数百から数千のOSSパッケージが積み上がっているのが実情です。「うちは開発をしていないから関係ない」と即断できるテーマではありません。

そもそも「再現可能ビルド」とは何ですか?

再現可能ビルドとは、同じソースコードから何度ビルドしても、まったく同じバイト列の成果物ができあがることを保証する仕組みです。これが成り立てば、第三者が手元でビルドし直して配布物と突き合わせるだけで、「ビルド環境や配布経路が乗っ取られて、ソースコードにない悪意あるコードが混入した」ことを検知できます。公開ソースには存在しないコードが配布物にだけ入り込むタイプのサプライチェーン攻撃への、根本的な防御策として注目されてきました。

今回の研究の主張は、「決定論的にビルドできること」と「第三者が実際に検証できること」は別物だという点にあります。検証する側は、ビルドを回す前に次の4つを外部から復元しなければなりません。

  1. どのソースコードの状態(コミット)から作られたのか
  2. どのビルド環境(OS・ツールのバージョン)で作られたのか
  3. どの依存パッケージのバージョンが使われたのか
  4. どういうビルド手順が実行されたのか

ところがこの4つは、レジストリに登録されたメタデータからは、しばしば読み取れません。ビルドが開発者それぞれの手元やCI/CD上で分散的に行われる「分散ビルド型」のエコシステムでは、ツールもワークフローもばらばらだからです。

どんな研究か——4大エコシステムで34,005件を実測

研究チーム(Oreofe Solarin、Kelechi Kalu、James C. Davis、Paschal Amusuoの各氏)は、「レジストリから取得できる情報だけを使う独立検証者」というモデルを定義し、それを自動化した検証パイプラインを実装しました。そして2026年5月時点での各パッケージの最新版、合計34,005件を対象に、実際に再ビルドして配布物と比較しています。

比較は、厳密さの異なる4段階で行われました。

段階 一致の条件
L1 バイト単位で完全一致(最も厳格)
L2 アーカイブのメタデータ(タイムスタンプ・圧縮方式・パーミッション)を正規化すれば一致
L3 ドキュメントや自動生成メタデータなど、実行されない差分を除けばコードは一致
L4 挙動としての等価性(今回は対象外)

結果:npmは約半数、crates.ioは約9割

検証パイプラインを完走できた成果物のうち、L1〜L3のいずれかで一致した割合は次のとおりです。

エコシステム 検証成功率(L1〜L3) パイプライン完走率(サンプル全体) プロヴェナンス情報を使った場合
crates.io(Rust) 87.4% 83.4%
RubyGems(Ruby) 79.4% 74.9% 85.1%
PyPI(Python) 64.6% 74.4%
npm(JavaScript) 52.9% 61.6% 73.2%

数値の読み方には注意が必要です。「検証成功率」と「プロヴェナンス情報を使った場合」は、ソースの復元方法ごとに、再ビルドを完走できた成果物の中で一致した割合です。前者はプロヴェナンスを使わずメタデータから推定した場合の値で、この方式での完走率はcrates.io 74.7%、npm 50.9%、PyPI 49.1%、RubyGems 70.9%です。表の「パイプライン完走率」列は、プロヴェナンス付きパッケージを含むサンプル全体の完走率(論文の表I)です。

ここで見落としてはいけないのが「パイプライン完走率」の列です。npmの場合、そもそも再ビルドの土俵に上がれたのがサンプル全体で61.6%、プロヴェナンスを使わずソースを推定した場合に限れば50.9%で、後者のうち検証を通ったのが52.9%です。土俵に上がれなかった主な理由は、配布物に対応するソースコードのコミットを特定できなかったことでした。「どのソースから作られたか」がそもそも分からない、という段階で脱落しているわけです。

crates.ioの成績が良かったのは、Rustのパッケージ形式がソースの由来を示すメタデータを成果物自体に埋め込む設計になっているためだと分析されています。仕組み側の設計が、そのまま検証可能性の差になっているという点は示唆的です。

なぜ検証に失敗するのですか?

大半は攻撃ではなく、ビルド環境の些細なズレが原因です。研究チームは失敗した134件を分析し、14種類の原因に分類しました。上位はこうなっています。

原因 件数 内容
ビルドツール・依存のバージョンずれ 47 メタデータファイル内のバージョン表記が食い違う
CI/CDによるソースの改変 38 公開ワークフローに記録されない加工がリリース時に入っている
ワークフローが生成した中間物 28 配布物にはあるが、素直に再ビルドすると生成されないファイルがある
タイムスタンプの保持の差 18 元の時刻情報が残る/残らないの違い
パッケージングのディレクトリ構成の差 14 格納パスが揃わない
ソースリビジョンの不一致 11 参照したコミットが配布物のものと異なる

実務的に重い意味を持つのは2番目です。「リリース時に、公開されている手順に書かれていない加工が入っている」——これは正当なリリース作業であることがほとんどですが、検証する側から見れば、悪意ある混入と区別がつきません。攻撃を検知するための仕組みが、正常な運用のノイズに埋もれてしまうのです。

GitHubの署名(プロヴェナンス)を付ければ解決しますか?

期待されているほどは効きません。少なくとも、今の記録内容のままでは。

プロヴェナンス(provenance/来歴)とは、パッケージがどのリポジトリの、どのコミットから、どのCI環境でビルドされたかを、暗号署名つきで記録する仕組みです。npmではGitHub ActionsとGitLab CI/CDで生成でき、Sigstoreの公開基盤で署名されます。SLSAというサプライチェーン安全性の枠組みでも中核に位置づけられています。

この研究が示したのは、次の3点です。

  • 普及率が低い:4エコシステムでの採用率は2.0〜6.6%にとどまる。
  • メタデータ単体の寄与は小さい:プロヴェナンス記録が検証成功率に直接寄与した分は、エコシステム別に0.8、1.5、3.6、−0.9ポイント(1つはマイナス)。
  • 効いているのは署名ではなく開発体制:プロヴェナンス付きパッケージの成績が良いのは、署名情報そのものの効果というより、署名を導入するようなプロジェクトのビルド・リリース運用がもともと整っているからだと分析されている。

ただし前掲の表のとおり、プロヴェナンスからソース情報を復元させると、npmは52.9%→73.2%、RubyGemsは79.4%→85.1%へと大きく改善します。つまり署名は「ソースの所在を突き止める手がかり」としては有効だが、「完全な再ビルド手順書」にはなっていない、というのが研究チームの結論です。何をどうビルドしたかまでは、まだ記録されていないのです。

査読前研究としての限界——鵜呑みにしないための注意点

この論文はarXivに投稿された査読前(プレプリント)の研究であり、結論は今後の査読過程で変わりうるものです。著者自身が挙げている限界も、実務で引用する前に押さえておく必要があります。

  • 数値は下限値:検証成功率は、この研究が定義した検証者モデルの能力にも左右される。より賢い検証者ならもっと通る可能性がある。
  • サンプルは無作為ではない:プロヴェナンスの普及率が低いため、署名の有無で層化して抽出している。各エコシステムの平均値としてそのまま読むのは適切でない。また対象は各パッケージの最新版1件のみで、バージョン間のばらつきは見ていない。
  • むしろ過大評価の可能性:公開リポジトリを辿れなかったパッケージを14.7〜42.4%除外しているため、報告値は「ソースが辿れたもの」に限った数字である。除外分を含めれば、実態はさらに厳しい。

したがって「npmの半分は危険」といった単純化はできません。検証に失敗した=改ざんされている、ではない点は、社内で共有する際に必ず添えるべき注意書きです。この研究が明らかにしたのは、汚染の有無ではなく、「汚染されていないことを確かめる手段が、まだ十分に整っていない」という構造的な穴です。

情シスはどうすべきか

1つめは、SBOMの整備を「部品表を作る」で止めないこと。成分表があっても、その成分が本当に表示どおりかを確かめる術がない——それが今回の研究が突きつけた現実です。まずは公的な手引に沿って自社の立ち位置を確認してください。

2つめは、調達・更新のタイミングでベンダーに1問だけ足すこと。「御社の製品に含まれるOSSコンポーネントについて、ビルドの来歴(プロヴェナンス)を記録・提示できますか」——この一言です。すぐに完璧な答えが返ってこなくても構いません。要求として存在することが、エコシステム側の改善圧力になります。研究チーム自身も、レジストリ運営者・メンテナ・標準化団体それぞれに対して、再ビルドに必要なメタデータを成果物に埋め込むべきだと提言しています。

仕組みが整うまでの現実解は、結局のところ地道な運用です。資産管理台帳の粒度を上げ、脆弱性情報が出たときに「どの製品の中にその部品が入っているか」を短時間で引ける状態にしておく。派手さはありませんが、ここが崩れていると、どんな検証技術も活かしようがありません。

現場目線の所感

正直に書くと、この研究を読んで最初に感じたのは徒労感に近いものでした。再現可能ビルドは、サプライチェーン攻撃に対する「ようやく見つかった正攻法」として語られてきた技術です。それが、技術的には成立しているのに「検証に必要な情報が揃っていない」という、あまりに地味な理由で機能していない。しかも失敗要因の上位は、悪意ではなく、ビルドツールのバージョン表記のズレやCIが吐き出す中間ファイルです。

ただ、情シスの現場感覚からすると、この結果はむしろ腑に落ちます。社内システムの棚卸しをすれば、たいてい似た構図に出くわすからです。仕組みは導入されている、ドキュメントも存在する、しかし実際に突き合わせようとすると細部が合わない。誰かが手作業で埋めていた工程がある——エコシステム全体で起きているのは、規模が違うだけで、日々のシステム管理で見慣れた綻びと同じ種類のものだと思います。だからこそ「開発者が頑張るべきこと」として切り離さず、調達側が来歴を尋ね、記録されていることを評価していきたい。その積み重ねでしか、2.0〜6.6%という採用率は動かないでしょう。

まとめ

  1. 再現可能ビルドは「作れる」だけでは意味がなく、第三者が「検証できる」かは別問題。査読前研究の実測では、検証を通ったのはnpm 52.9%、PyPI 64.6%、RubyGems 79.4%、crates.io 87.4%(いずれもプロヴェナンスを使わずソースを復元し、再ビルドを完走できた成果物の中での割合)。
  2. 失敗の主因は攻撃ではなく、ビルドツールのバージョンずれ・CI/CDでの非公開な加工・生成される中間ファイル。正常な運用のノイズが、改ざん検知を埋もれさせている。
  3. プロヴェナンス署名は採用率2.0〜6.6%で、ソースの所在特定には効くが完全な再ビルド手順にはなっていない。情シスは、SBOM整備を「作って終わり」にせず、調達時に来歴の記録・提示を問う運用へ広げたい。

関連記事

出典

タイトルとURLをコピーしました