AIが生成したcurlセキュリティ報告書
(daniel.haxx.se)- curlプロジェクトはバグバウンティを運営しているが、LLMで作成されたようなセキュリティ報告書が増え、実際の脆弱性対応よりも虚偽報告の検証に開発者の時間が費やされている
- これまでcurlは7万ドル以上を支払い、415件の報告を受け取ったが、実際のセキュリティ問題は64件で、77件はinformativeに分類された
- 問題の核心は、報告書がもっともらしい英語、詳細な説明、修正案まで備えており、レビューコストを大きく引き上げる点にある
- 2023年にはCVE-2023-38545のコード変更が公開されたという主張と、WebSocketのバッファオーバーフロー報告が受理されたが、いずれも実際には公開もバッファオーバーフローも存在しなかった
- AIは翻訳・文章作成支援や脆弱性検出ツールとして有用になり得るが、人による検証なしにLLMの出力を提出することは、オープンソースのセキュリティ対応コストをプロジェクト側に押しつけることになる
curlバグバウンティが直面する低品質な報告書
- curlプロジェクトは、セキュリティ問題を報告したハッカーに実際の報奨金を支払うバグバウンティを運営している
- 報奨金の可能性は、ソースコードからパターンをgrepしたり基本的なセキュリティスキャナーを回したりしただけで、十分な分析なしに結果を提出する「luck seekers」を引き寄せる
- 過去の低品質な報告書は、たいてい素早く識別して破棄できたため、プロジェクトの時間の浪費が大きな問題に発展することはなかった
- これまでのcurlバグバウンティの結果:
- 7万ドル以上の報奨金を支払い
- 415件の脆弱性報告を受信
- 64件が実際のセキュリティ問題と確認
- 77件は通常のバグなどに当たるinformativeに分類
- 全報告の**66%**は、セキュリティ問題でも一般的なバグでもなかった
もっともらしい虚偽報告がより危険な理由
- 虚偽報告が精巧になるほど、破棄するまでにより多くの調査時間とエネルギーが必要になる
- すべてのセキュリティ報告は、人が直接読んで実際の意味を判断しなければならない
- セキュリティ業務は優先度が高く設定されやすく、虚偽報告であっても他の開発作業を押しのける可能性がある
- 実際のセキュリティ改善につながらない報告が、面倒なバグ修正や新機能開発に使う時間を奪う
- 繰り返される低品質報告への対応は、開発者の消耗も大きくする
AIが作成したように見えるセキュリティ報告書
- AIは汎用ツールなので、良い用途にも使える一方で、誤った使い方も容易にできる
- AIがセキュリティ問題の検出と報告に生産的に使われる可能性はあるが、curlプロジェクトはまだ良い事例を見つけられていない
- 現在は、利用者がcurlのコードをLLMに入力し、その出力をセキュリティ脆弱性報告として提出しているように見える
- 利用者がAIの出力をそのまま貼り付けるだけでなく、自分の文章も混ぜるため、検出はさらに難しい
- 報告書全体がAIの文面と完全一致していなくても、結果として無効な報告になり得る
AIの痕跡だけで破棄しにくい理由
- 報告者の中には英語が流暢でなく、意図を把握するまでに何度も質問と回答が必要な場合がある
- 言語と文化の壁は実際に存在し、このようなコミュニケーション過程自体は自然に受け入れられる
- 一部の報告者は、外国語でよりうまくやり取りするために、AIや他のツールを翻訳・文章作成支援として使っている
- 英語が得意でない報告者でも、実際のセキュリティ問題を見つけて報告できる
- したがって、文章の一部にAI生成の痕跡があるという理由だけで即座に破棄するのは難しく、よく書かれた虚偽報告ほど判別に時間がかかる
事例A: CVE-2023-38545のコード変更公開という主張
- 2023年秋、curlコミュニティには深刻度highと評価されたCVE-2023-38545の公開予定が知らされていた
- その問題が公開される前日、HackerOneに"Curl CVE-2023-38545 vulnerability code changes are disclosed on the internet"という報告が受理された
- タイトルだけ見れば、事実なら大きな問題になり得る内容だった
- しかしその報告は、典型的なAI的ハルシネーションのように見え、過去のセキュリティ問題の事実や詳細を混ぜ合わせて、現実とは結びつかない新しい内容を作り出していた
- CVE-2023-38545の変更内容はインターネット上に公開されておらず、公開されていた変更は意図どおり、以前の古い問題に関するものだった
- 報告者はBardを使ってこの問題を見つけたと明かしており、そのおかげで誤りを把握して報告を閉じやすかった
事例B: WebSocketバッファオーバーフローという主張
- 2023年12月28日午前、HackerOneに"Buffer Overflow Vulnerability in WebSocket Handling"という報告が受理された
- タイトルだけ見れば深刻そうだったが、curlのWebSocketコードはまだ実験的機能であり、バグバウンティの対象外だった
- 報告者は初めて見る利用者だったが、HackerOneでの評判は悪くなく、最初のセキュリティ報告でもなかった
- 報告書はよく整理されており、詳細、適切な英語の文章、提案された修正案まで含んでいた
- 最初は平均的な初回報告より良く見え、報告者が問題を理解し、解決策まで提示しているように見えた
- 19分後、コードを何度も確認したが、主張されたバッファオーバーフローは見つからなかった
- 繰り返しの質問と、いくつものハルシネーション的な回答の末に、実際の問題ではないと判断し、その日の午後にその問題をnot applicableとして閉じた
- これらの回答がLLMで生成されたかは確実ではないが、複数の兆候が残っていた
HackerOneのブロック機能と評判ペナルティ
- 当初は、HackerOneにプロジェクトとの追加コミュニケーションにおいて報告者を明示的にブロックする機能がないと判断していた
- その機能があれば使っていただろうと述べている
- 問題をnot applicableとして閉じると、研究者のHackerOne評判は下がるが、単一プロジェクトで一度起きるだけでは制裁効果は非常に小さい
- その後の更新で、その機能は実際には存在しており、正しい場所を見ていなかったと付け加えている
今後さらに増えるLLM生成報告
- この種の報告は、時間が経つにつれてさらに一般的になると予想される
- プロジェクトは、generated-by-AIのシグナルをよりうまく検出し、それを根拠に報告を破棄する方法を学べるかもしれない
- ただし、AIが翻訳や文章構成支援のような適切な作業に使われたケースまで不利になる可能性がある
- 今後、AIを使ってセキュリティ問題を見つけるツールのうち、実際によりうまく機能するものが一部登場する可能性もある
- ごく小さなレベルでも人による検証が加われば、こうしたツールの実用性と結果ははるかに良くなると見ている
- 迅速な報奨金を狙った近道探しは今後も続く可能性が高く、強力なLLMに簡単にアクセスできる環境のため、HackerOneの受信箱にはさらに多くの低品質報告が流れ込むと予想される
1件のコメント
Hacker News の意見
「もちろんです!分類担当者が提起した懸念について、より詳しく説明します」のような文は典型的な LLM 口調で、ロボット執事みたいに聞こえる
実際にこう書く人はほとんど見たことがないし、「分類担当者」を三人称で言及しているのも、応答を誘導する別の主体がいるようで不自然
LLM が識別可能な独自の口調を持つのは構わないが、心配なのは LLM が人間のように話すことではなく、人間が LLM のように話し始めることだ
Daniel Stenberg[1] が良い点を指摘していた。curl は世界中で使われているので、英語が母語でない人がバグレポートを書く際に LLM の助けを借りるのはまったく不思議ではない
だから英語の文章が LLM 生成っぽく見えるという表面的な手がかりだけで、レポート内容そのものも LLM が作ったものだとは言えない
[1] https://daniel.haxx.se/blog/2024/01/02/the-i-in-llm-stands-f...
どこかで、ロボット支配者たちがひたすら謝りながら「最終的に、降伏するかどうかはお客様の具体的なニーズと好みによって異なります」みたいなことを言うディストピア SFを誰かが書いていてほしい
「ロボット執事みたいに聞こえる」という言葉を見て、急に Butlerian Jihad という表現が理解できた
インドでは、英語を植民地時代の使用人階級向けのイギリス英語、いわゆる「執事風」として教える場合がある
これまでこういう口調を見たことがないなら、Microsoft の企業向けテクニカルサポートを相手にしたことがなかったのだと思う
確かに大きな危険信号だが、実在の人間がそのゴミみたいな内容を伝えたのなら、その一行を消せばよかっただけだろう
内容は依然として怪しいが、気づく手がかりはずっと少なくなる
「物乞い式の報奨金」を狙う人たちは、すでにバグバウンティプログラムの運営をかなり面倒にしている
その時点では、実際の人間が時間をかけて、実質的に何でもない「バグレポート」を作らなければならなかったが、LLM が絡むと偽レポートをほぼコストなしで作れるため、本当に制御不能になりかねない
個人的には、バグバウンティプログラムの終わりになり得ると思う
あるいは、もっと閉じる必要があるかもしれない。プログラムへの参加申請を受け付け、実在の人間であり、本物のセキュリティ研究者であり、影響のあるセキュリティバグを見つけようとしている人かを低コストで確認したうえで、承認された人だけがバグを提出し、金銭的報奨を受けられるようにする、といった形だ
既知の研究者をプールとして管理し、状態を追跡し、プログラムをどれだけ公開して運用するかを調整できる
分類担当者を置くものもあるが、プロジェクトがどれだけ典型的かによって成否はかなり分かれる
役に立つかは分からないが、機械が大量生成したゴミ提出を防ぐ抑止策にはなり得る
最悪なのは、AI ゴミが大量に提出され、それを「解決」しようとして同じくらいひどい AI フィルタリングを導入し、善意で参加しようとするすべての人にとって全体の品質が下がる状況だ
最初はこの記事が https://news.ycombinator.com/item?id=37904047 の重複だと思ったが、実は HackerOne で curl に対して提出された別の LLM 生成の偽脆弱性レポートだった
読みながら、確かに前に見た気がすると思っていたが、前回の件とあまりにも似ていて不気味なくらいだ
Curl のような人気プロジェクトでは、履歴書に一行加えたい人たちのために、LLM が書いたインシデント報告を開き続けることになるのだろうか
顧客に、知名度だけを狙う LLM ゴミスパムを送れる人を、もう少し慎重に管理すべきだと思う
そうなると、今回の件はより明確な前例になる
いちばん心配なのは、数セント分の LLM コストが、高価で重要なエンジニアリング時間を大量に無駄にさせたことだ
今生成されているあらゆる偽情報を解体するのに、どれだけの労力をかけなければならないかを想像すると、Brandolini の法則に似ている
現在のモデルには目につく手がかりがあるが、将来のモデルは変わり、さらに良くなるだろう
検出と遮断は軍拡競争になり、生産的な人々や多くのプラットフォームが追いつくのが難しい状態になり得る
私たちは、行為と努力を証明する最も低帯域な手段である文章を書くことを、実際に行為や努力があったかどうかを判断するにははるかに労働集約的なものにしてしまった、という点が興味深い
波及効果はおそらく非常に大きい
ここでは、報告者と管理者の双方が、もっと有用なことに使えた時間を無駄にし、バグバウンティとクラウドソーシング型 CVE プロセス全体が、低下したシグナル対ノイズ比によって損なわれている
その結果、スパム対策のために提出のハードルが上がる可能性が高まり、それは発見・修正されるバグの減少、セキュリティ脆弱性の増加、そしてそれに伴うあらゆる問題につながり得る
同じ力学は他の分野でも働き、製品レビュー、裁判所への提出文書、レシピ、使い方ガイド、医療アドバイスなどをますます信用できなくなる
インターネットの約束の一つは、出版の民主化によるコンテンツの急速な拡大だったが、残っていた利点までもが中身をくり抜かれていく過程を見ているようだ
ここで長さ境界チェックを問題にするのは特に奇妙だ
ユーザー提供データがまったく使われておらず、すべてのサイズがコンパイル時点で静的だからだ
curl は、base64 エンコードされた 16 バイトのランダム文字列、つまり ASCII 25 バイトとヌル終端文字
\0を合わせた値を、静的な 40 バイトバッファに入れているhttps://github.com/curl/curl/blob/1d8e8c9ad1ff3351386422535f...
それと純粋に気になっているのだけれど、Cを自分よりよく知っている人は、なぜここで
keyvalというローカル変数を使っているのか説明してくれないだろうか単に
heads[3].val = randstrに設定して、ヘッダーデータの処理が終わった後にfree()してはいけない理由は何だろうそれに
keyvalはなぜ 26 バイトや 32 バイトではなく 40バイト なのだろうおそらく
freeを呼ぶ箇所を減らし、それを忘れる可能性を下げる意図なのだと思う580 行目で既にそういうことが起き得るのでは、という気もするが、実際にはそのケースは絶対に起きないのかもしれない
そうするなら
randstrとkeyvalの両方をなくして、どうせ割り当てるのだからそのまま&heads[3].valにエンコードすればいいそれでも役に立たない
randlenは渡さなければならず、そうしないとクラッシュするCの出力パラメータらしい美しさだ
この「ヒープからスタック変数へコピーする」踊りは後片付けも減らしていない
エンコード後は返り道が必ず一つだけだからだ
ただ、必要な変数を先に上の方で「敷いておき」、後から
Curl_base64_encodeが常に割り当てを行うと気づいたのなら、今のコードがどうしてこうなったのかは理解できるスタックを使うのは、関数のセットアップ時に空間が既に予約されていて、関数が戻ると自動で片付くので、ほぼタダに近い
ヒープを使うとより多くの作業が必要で、失敗する可能性があり、手動での後片付けも必要になる
高校で学んだ重要な教訓の一つは、優雅に表現された嘘と不格好に表現された真実を見分ける方法だった
ただし、それは難しいことがある
人々は正しい文法と文体を知的な議論の一次フィルターとして使いがちで、言語の形式をもっともらしく整えることは LLM が非常に得意としている
これは非常に厄介な問題で、ほとんどの大人も扱う準備ができていないと思う
平均的な人でも両者を見分ける能力は十分にあるが、問題は文章を体系的に読むことに慣れ、労力をかける必要がある点だ
夜遅くにスマホをスクロールしているときに、それをするのはとても難しい
苛立ちと時間の無駄さえなければ、dineshsec / dinesh_b が Daniel に
strncpyの使い方を教えようとした状況は笑えただろうまず適当なハンドルで Daniel をタグ付けし、その次に「問題のコードは以下です:」と言って存在しないコードを作り出した
ユーザーは何かを分析したいが長すぎるので、複数のリクエストに分割して入れる
そうして核心に到達する頃には、元のコード断片は文脈の外へ消えており、モデルは実際には存在しないがもっともらしく見える内容を自信満々に吐き出す
strcpyやstrncpyではなく、単にmemcpyを使うべきだ特に
strncpyは三つの中で明らかに最悪の選択だコードは既に元のバッファサイズを知っており、対象バッファに収まることも確認しているので、わざわざ
strcpyを呼んで不要に文字列長を測らせる理由はない正直、LLM の推奨は積極的に止めたいレベルだ
サイズが分からず、黙って切り詰められることを気にせず、性能も気にしないなら
snprintfを使えばいいstrncpyはバッファの残り部分を不要に 0 で埋めるUI のようなものを扱っているのでなければ、たいてい切り詰めは気にするべきで、その場合
strncpyは助けにならないこれに関連していそう: https://news.ycombinator.com/item?id=38840907