複数パッチが必要な脆弱性修正、オープンソースを危険にさらす恐れ

脆弱性管理には、一種の定石があります。CVEにリンクされたパッチが提示され、誰かがそれを適用し、チケットがクローズされる——この流れが、オープンソースの修正の大半をカバーしています。しかし、その定石とは異なる形で処理されるケースもあります。それは2つ以上のコミットが連続して行われ、最初のコミットでは欠陥がそのまま残ってしまうというパターンです。

Image

テキサス大学ダラス校の研究者らは、National Vulnerability Databaseに登録されている、1999年から2025年の間に記録された、複数のパッチが紐づくオープンソースCVE1,646件を調査しました。こうしたケースは全体のごく一部に過ぎず、パッチがリンクされたオープンソースCVE全体のうち、およそ15件に1件の割合です。しかし運用上のリスクの重みは、最初のパッチと最後のパッチの間の期間、つまりソフトウェアが依然として脆弱なままになっている「窓」の部分に集中しています。

調査対象群では、CVE1件あたり平均2.55個のパッチが必要とされており、その負荷はプロジェクトごとに偏りが見られます。複数のリリースラインを同時に維持しているImageMagickでは、修正のおよそ3分の1で複数のコミットが必要となっており、これは同じ修正をサポート対象の全バージョンに移植する作業に起因する比率です。

単一のパッチでは不十分となる3つのパターン

研究チームは、複数パッチを要するケースを3つのグループに分類しました。最も規模が大きいのは、脆弱性が複数の場所に存在するケースです。似たようなバグを含むコードが、別々のブランチやメソッド、プロジェクトにまたがって存在しており、Gitでは1つのコミットをすべてのブランチに同時適用することができないため、ベンダーは変更点を影響を受ける各箇所に個別に移植する必要があります。異なるブランチやプロジェクトにまたがる修正は、サブカテゴリーとして最大規模となる830件を占めていました。

2番目のグループは、セキュリティ上の変更に、暫定的な回避策やチェンジログの記載、単独でコミットされたドキュメント更新といった関連作業が組み合わされているケースです。そして3番目のグループは、最もリスクが高いものです。これは欠陥のある修正、つまり最初のパッチが脆弱性の一部を見落としているか、あるいは新たなバグを生んでしまっているケースです。不完全な修正だけで641件に上り、このセットの中で2番目に大きなサブカテゴリーとなっています。

CVE-2012-0038として追跡されている、LinuxのXFSファイルシステムにおける整数オーバーフローは、まさにこのパターンを示す事例です。最初のコミットでは境界チェックが追加されましたが、これは符号なし整数を返すヘルパー関数に依存しており、そこにコードが符号付きとして扱う値が渡されていたため、チェックを回避できてしまう状態でした。2つ目のコミットで変数の型が変更され、この抜け穴が塞がれました。完全な修正が完了したのは、最初の修正から18日後のことでした。

検知ツールでは残存リスクを見逃す

自動化されたツールは、部分的な修正と完全な修正を見分ける上でほとんど役に立ちません。研究者らは、CodeBERT、UniXcoder、LineVul、Devign、ReVealを含む7つの検知モデルを、不完全な修正のデータセットに対して実行し、それぞれに修正後のコードを脆弱か安全かに分類させました。

すべてのモデルで、精度とF1スコアはいずれも50%を下回り、著者らはこれをランダムな推測よりも悪い水準だと指摘しています。セキュリティパッチが変更するのはコードのごく一部にすぎないため、これらのモデルは修正前・修正途中・修正後のバージョンの関数に対して、同じラベルを付けてしまう傾向があります。

評価対象となったモデルは、オープンソースの研究用システムであり、公開データを用いてテストされたものです。本研究の共著者であるWeiliang Qi氏は、研究チームが意図的に商用製品をテスト対象から除外したと述べています。「私たちのテストケースは公開されている脆弱性記録から取られているため、独自(プロプライエタリ)なツールは同じCVEに対するシグネチャをすでに持っている可能性があり、真の汎化能力なのか、それとも事前知識によるものなのかを区別することが難しくなります」とQi氏はHelp Net Securityに語りました。商用製品がどのような性能を示すかについての同氏の見立ては、その動作原理に基づいています。「私たちの知る限り、多くの商用ツールはシグネチャマッチングやコードパターンといった技術に依存しており、これは私たちの評価で用いたツールの基盤となっているアプローチと類似しています。そのため、未知の不完全な修正や複数箇所にまたがる修正の検知においては、同様の限界に直面すると予想しています」。

コードベース内の脆弱なコードのコピーを探し出すツールも、同様の状況で苦戦を強いられました。オープンソースのクローン検知ツールであるReDebugとFIREの2つを、複数箇所にまたがる修正のケースに適用し、最初のパッチを使って後続の該当箇所のシグネチャを構築させました。FIREの真陽性率(繰り返し出現する脆弱なコードを検知する能力)は、90からおよそ52まで低下しました。こうしたケースでは、脆弱な箇所同士の違いが大きいため、最初の箇所から構築したシグネチャでは他の箇所を見逃してしまうのです。

パッチ間の「窓」

こうした空白期間は、タイミングの問題によって実際の露出リスクへと変わります。複数パッチを要する修正のうち、31.7%は最初のコミットから最後のコミットまでに1日以上を要しています。ブランチをまたぐ移植やプロジェクトをまたぐ移植ほど、この遅延は長くなる傾向があり、この遅延自体が競争を生み出します。ひとたび1つのブランチに公開された修正が適用されると、攻撃者は同じリポジトリを読み取り、未修正のブランチにある同等の脆弱性を特定し、移植が届く前にそれを悪用できてしまうのです。

CVE-2023-4226として追跡されている、Chamilo LMSにおける任意ファイルアップロードの欠陥も、この経過をたどりました。まず暫定的な回避策が公開され、正式な修正はその16日後に続きました。

Qi氏は、データが裏付ける範囲について慎重な姿勢を見せています。「この期間中に実際に悪用が行われたという直接的な証拠は見つかっていません。私たちの研究が測定しているのは攻撃者の活動そのものではなく、露出している期間の長さです。したがって、現時点で私たちが述べているリスクは構造的なものです」と同氏は述べています。同氏は、関連する兆候として、プロジェクトをまたいだコード再利用がすでにセキュリティコミュニティで深刻な問題として扱われている点を指摘しています。「リスクは実在すると私たちは考えています。その間接的な一例として、異なるプロジェクト間のコード再利用に起因する脆弱性はすでにコミュニティの注目を集めており、VUDDYやMOVERY、FIREといった一連の検知ツールの開発につながっています」とQi氏は述べました。「複数パッチのケースは、単一プロジェクト内で同様のパターンを示すものであり、ある箇所での早期のパッチが、まだ修正されていない類似の欠陥についての手がかりを露呈させてしまう可能性があります。私たちは、これらが同程度の悪用リスクを抱えていると考えています」。

パッチ記録自体にもノイズが混入

パッチ記録そのものにも、分析の妨げとなる要因があります。複数パッチのケースのおよそ5.8%には、READMEの編集やバージョン番号の更新、テストファイルなど、セキュリティとは無関係なコミットが含まれており、これがデータに基づく自動分析のコストを押し上げています。

CVE-2022-2522として追跡されている、ある記録では、ユーザーが誤りを指摘したにもかかわらず、ベンダーが修正を拒否したため、セキュリティ修正の親コミットとなっていた誤ったコミットがそのまま残されていました。パッチを逆算する形で構築された脆弱性データセットは、こうしたノイズをそのまま引き継いでしまいます。さらに、後のコミットを逆算すると、脆弱なコードと修正済みコードの両方の特徴を併せ持つ中間的な状態が生じてしまうことがあります。

リンクされたパッチの適用をもって脆弱性のライフサイクルの終わりとみなす扱いは、一般的なケースでは機能します。しかし、一連の修正が必要となるケースでは、追加の確認作業が求められます。単一のコミットしかリンクされていない深刻度の高いCVEについては、後続のパッチがないかを確認し、公開前にその修正がどのブランチに属するものかを見極める必要があります。NVDのエントリーに付けられたラベルは、オープンソースの欠陥のかなりの割合において、あくまで対処の「始まり」を示すものにすぎず、その先はコードそのものが物語っているのです。

翻訳元: https://www.helpnetsecurity.com/2026/07/23/research-multi-patch-vulnerability-fixes/

ソース: helpnetsecurity.com