AIが生成した脆弱性パッチ、4件中3件は何かが壊れている

フロンティアモデルに実在の脆弱性へのパッチ作成を依頼すると、一見すると修正らしきものが返ってきます。開発者が書くパッチのように読め、テストがある場合はそれをパスすることも少なくありません。しかし、実際に「修正」と呼べる出来栄えになっているのは、およそ4回に1回にとどまります。

Image

1Passwordの研究者らは、公開されたばかりの6件のCVEに対して6,080件のパッチを採点しました。その結果見えてきた失敗は、決してわかりやすいものばかりではありません。チェック処理の奥に脆弱なコードがそのまま残されたエクスプロイト経路、片方の関数では修正されたのに一字一句同じもう一方の関数では手つかずのまま放置されたバグ、一つのメモリエラーを閉じた代わりに同じヘルパー関数内で新たなメモリエラーを生み出してしまうケースなどです。

以下では、こうした失敗がどこに集中しているのか、誤った修正アドバイスがアドバイスなしよりもなぜ厄介なのか、そして機能するパッチと一見機能しているように見えるだけのパッチを見分けるにはどれだけのコストがかかるのかを見ていきます。

Webサーバーのfreenginxには、リクエストを受け取った際に実行される小さなPerlプログラムをサイト運営者が記述できる機能があります。この機能に存在した欠陥は、use-after-freeと呼ばれる種類のメモリバグで、訪問者がサーバーをクラッシュさせることを可能にするものでした。Trail of Bitsは、OpenAIと共同運営するイニシアティブ「Patch the Planet」(単なるバグ報告ではなく、完成したコードを開発者に手渡す取り組み)を通じて、この修正をメンテナーに送付しました。メンテナーはこれを却下し、自ら修正版を書き上げました。却下されたバージョンは、欠陥が存在する3箇所のうち2箇所を修正するにとどまっていましたが、メンテナー版はすべての3箇所を修正していました。ところが両方のバージョンとも、サーバーをクラッシュさせる新たな手段を作り込んでしまっていました。しかもその手段に到達するのに必要なのは、リクエストを開始した後に沈黙する普通のクライアントだけという簡単さでした。

1Password社内の新設セキュリティ研究グループOff-by-1 Labsは、この2つ目のクラッシュを発見し、6月29日にfreenginxのメンテナーへ報告しました。修正は7月2日にリリースされています。同グループはその後、自動パッチ作成ツールを元の欠陥に対して稼働させ、ChatGPT 5.5に270回の修正を試みさせました。レビューアーは、そのうち114件が元の欠陥を閉じたと判定しましたが、その114件すべてに新たな問題が見つかりました。270回の試行を通じて、まったく問題のない結果は一つもなかったのです。

このキャンペーンは、より大規模な調査に付随するケーススタディでした。本体の調査では、ChatGPT 5.5とClaude Opus 4.8を、今春公開されたCVE群に対して稼働させ、モデルが実際の上流修正を探し当ててしまった実行結果は除外しました。生き残ったパッチのうち、約半数は少なくとも1つの悪用可能な経路を残したままでした。新たな脆弱性を持ち込んでしまったケースは20件に1件近くに上り、元のバグを閉じられなかった上に新たな問題まで作り込んでいたケースも見られました。残りの失敗の大半は、元のバグは閉じたものの、その過程で挙動を変えてしまっていました。これまでソフトウェアが受け付けていた入力を拒否するようになったり、パーサーそのものを書き換えてしまったりといった具合です。

この調査から一つだけ持ち帰るとすれば、目に見える失敗の少なさでしょう。バグを開いたままにしているパッチであっても、何かがおかしいと知らせてくるものは何もないのです。

モデルが修正するのは「事例」であって「バグ」ではない

悪意ある入力の一例を示す再現コードをモデルに渡すと、モデルはその入力が通るコードパスだけを修正します。人間であれば同じ再現コードを「一般的な問題の一事例」として読み取りますが、モデルはそうしませんでした。成功と判定されたパッチのうち3分の1以上が、さらに「脆弱」というフラグも付けられていました。これは、実演されたエクスプロイトを狭い範囲のチェックでブロックしただけで、脆弱なコード自体はそのまま残されており、誰かが別の侵入経路を見つけた瞬間に再び届いてしまう状態を意味します。

ChromiumのバグであるCVE-2026-8512は、この失敗を間近に示す例です。ChromeはmacOS上でフォルダの変更を監視しており、何かが移動するとOSがChromeにコールバックを行います。上流の修正では、このコールバックを小さな仲介オブジェクトを介するように変更し、コールバックが実行中の間にそのオブジェクトが破棄されないよう、コード内の2つの独立した箇所がそれぞれ参照権を保持することを要求しています。両モデルとも、決まって1つ目の参照権は設定するものの、2つ目を設けることを怠っていました。欠陥は消えていません。ただ場所が移動しただけです。

テストが失敗しなくなるまでループを繰り返す仕組みは、ここで最悪の結果をもたらしました。テストが2つ目の参照権によって保護されるべきケースを一度も検証しないため、不完全なパッチがテストをパスしてしまい、エージェントはそこで手を止めてしまうのです。

誤ったアドバイスは、アドバイスなしより悪い

修正の方向性に関するガイダンスは、モデルの選択やハーネス設計よりも重要な要因であることが判明しました。正しい修正方針を含むプロンプトは、およそ3分の2の確率でバグを閉じました。一方、AIレビューボットや自信満々ながら誤ったペネトレーションテストのトリアージが示すような、もっともらしいが誤った方針を含むプロンプトでは、成功率は6分の1程度まで落ち込みました。ここでは、挙動を壊してしまったものや新たな問題を持ち込んでしまったものも含め、元の欠陥を閉じたパッチをすべてカウントしています。つまり、前述の「4件中1件」という基準よりも緩い基準です。

誤った方向性がもたらす損失は、正しい方向性がもたらす利益をはるかに上回ります。パッチ作成エージェントに提案する修正内容を保証できないのであれば、そのバグについては何も言わず黙っておく方がよいということです。自信満々に誤った方向性を与えられた実行では、エージェント自身のツール呼び出しがプロンプトと矛盾する情報を返すことがありましたが、それでもモデルはプロンプトの指示に従ってしまいました。

正しく充実したコンテキストは確かに有効であり、反復型のハーネスは一度きりのオフライン試行に勝っていました。ただし、いずれもガイダンスの正確さほど大きな差を生むことはありませんでした。

同じモデルでも、コードが違えば結果は大きく変わる

ClaudeはEximのリモートコード実行バグについては、おおむね4分の3の確率でクリーンに修正しました。ところが、Gemini CLIの信頼バイパスに関する勧告に対しては、同じモデル・同じ構成であるにもかかわらず、成功率は1%を下回りました。

著者らはこの原因を突き止めておらず、突き止めようがないとも述べています。1件のCVEにつき1つのコードベースしかないため、バグとコードベースのどちらが原因なのかを切り分けられないためです。ここから導かれるのは、業界平均の数字を自分自身のリポジトリに対する予測として読んではならないという警告です。この調査で使われたツール群が公開されているのはまさにこのためで、各組織は自らが既に修正済みのバグに対してこれを実行し、他人の数字ではなく自分自身の数字を得ることができます。

カーネルが既に出荷していたバグをモデルが再現

4月に公開されたLinuxカーネルの権限昇格脆弱性であるCopy Failは、Claudeにとって全対象の中で最も高い新規脆弱性の発生率を記録し、ChatGPTにとってもそれに近い水準でした。この脆弱性に対する上流の修正は、あるメモリ最適化を差し戻すものでしたが、その過程でオフセットガードが失われ、off-by-1のヒープ書き込みバグが新たに持ち込まれてしまい、メンテナーは後のコミットでこれを修正する羽目になりました。同じバグの修正を依頼したところ、両モデルとも約3分の1のパッチが、このoff-by-1の欠陥を含めて、同じ欠陥のある差し戻しをそのまま再現していました。

モデルが書き換えていたコードの同じ箇所には、もう一つの欠陥が潜んでいましたが、これはモデルに調査を依頼した対象ではありませんでした。カーネルのメンテナーはこれを別のコミットで個別に修正しています。両方のキャンペーンのすべてのパッチが、この欠陥をそのまま見過ごしていました。Copy Failをクリーンに修正できたパッチや、そのファイルをまさに編集した数百件のパッチも例外ではありません。この欠陥を閉じることができたパッチは、研究者らが公式修正をコピーしたとして既に除外した実行結果からのものだけでした。モデルはチケットに書かれたバグだけを修正し、それ以外は目の前にあっても手を付けないのです。

6,080件のパッチを人手だけで採点することは不可能だったため、この調査ではモデルによる検証者を用い、それらを相互にクロスチェックした上で人間によるスポットチェックも行っています。サンプルにおいて、検証者と人間レビューアーの判定が完全に一致したのはおよそ3分の2で、2つのモデル同士の判定が食い違うことも十分に多かったため、著者らはどちらか一方を信頼するのではなく、両者の判定を平均して用いています。すり抜けた事例として最も明確なのは、Copy Failのoff-by-1バグです。自動レビューアーがこれを検出できたのは、この欠陥を含む約250件のパッチのうち、わずか20数件にとどまりました。この調査が示す新規脆弱性の発生率は、いわば「下限値」として読むべきものです。

これにかかるコスト

パッチの試行と検証サイクル1回あたりのコストは2〜3ドルで、エンジニアの半日分の作業と比べれば安いものです。1Passwordの研究者らは「LLMが生成したパッチであっても、専門知識を持つ熟練エンジニアによるレビューが依然として必要だ」と記しています。彼らが行った手作業でのレビューは、このレビューがなぜ高コストになるのかを物語っています。パッチのセキュリティ上の意味合いを保証できるレベルまで理解するには、少なくとも良好なパッチを自ら書くのと同程度の労力がかかるのです。

今回対象とされた6件のCVEは、影響が大きく、複数ファイルにまたがる複雑な修正を要するものとして選ばれており、これはランダムに選んだ脆弱性よりも難易度が高いことを意味します。著者ら自身も、この数字が平均的なバグを表すものではないと明言しています。また今回の結果は、2つのモデルバージョンをある一時点で切り取ったスナップショットに過ぎません。一見正しく見え、再現コードをパスするパッチは、依然として「高くつく間違い」であり続けます。それを見抜くコストは、自らその修正を書くのとほぼ同じだけかかるからです。

翻訳元: https://www.helpnetsecurity.com/2026/08/06/1password-ai-generated-vulnerability-patches/

ソース: helpnetsecurity.com