悪用可能性の検証とは?

悪用可能性の検証とは、誰かが修正に時間を費やす前に、攻撃の安全なバージョンをコードに対して実行し、報告された脆弱性が悪用できるかどうかを確認する工程です。静的解析ツールは危険なパターンに一致するコードを報告しますが、その多くは誤報です。入力がそれより前に検査されている、そのコードが実行されることがない、フレームワークがすでに出力をエスケープしている、といった場合です。検証によって、攻撃者が悪用できる検出事項とできない検出事項を仕分けます。

静的解析で誤検知が発生する理由

静的アプリケーションセキュリティテスト(SAST)は、ソースコードを実行せずに読み取ります。そのためすべての行を素早く網羅できますが、実行時に何が起きるかは推測するしかありません。誤検知は通常、次のいずれかが原因で発生します。

  • 認識されないサニタイザー。入力はツールが把握していない検証関数を通過するため、ツールはその入力を依然として危険なものとして扱います。
  • ツールがモデル化していないフレームワークの保護。多くのテンプレートエンジンは出力を自動的にエスケープし、多くのデータベースライブラリはクエリを自動的にパラメータ化します。
  • 文脈の欠落。管理者チェックの後ろにあるルート、定数でしか呼び出されない関数、本番環境で無効になっている機能などです。
  • 出荷されないコード。テストフィクスチャ、サンプル、デッドコードが、本番コードと同じようにスキャンされます。
  • パターンマッチング。危険なコードの形に一致するルールは、その形のものをすべて指摘します。

ツールは判断できないとき、通常は報告します。脆弱性の見逃しは誤報よりも大きなコストになるためです。

誤報のコスト

アラートが出るたびに、誰かが時間をかけて追跡し、却下しなければなりません。さらに、誤検知率が高いと、チームはそのツールを無視するようになります。Johnsonらによる2013年の研究「Why Don't Software Developers Use Static Analysis Tools to Find Bugs?」は、開発者がこれらのツールを避ける主な理由の中に、誤検知と警告の提示方法があることを明らかにしました。Googleの社内解析プラットフォームTricorderは、実効誤検知率を10%未満に保つことをチェックに義務付けており、この率は開発者が警告を役に立たないと判定した頻度で測定されます。

スキャナーの精度を測る

スキャナーを表す数値は2つあります。

  • 適合率:報告された問題のうち、本物である問題の割合。
  • 再現率:本物の問題のうち、報告された問題の割合。

OWASP Benchmarkは、数千の小さなテストケースで両方を測定します。約半数は意図的に脆弱に、約半数は意図的に安全に作られているため、ツールはすべてを指摘するだけでは高いスコアを得られません。スコアは、ツールの真陽性率から誤検知率を引いた値(Youden指数)です。

OWASP Benchmark for Java(2,740件のテストケース)では、Cyfendoは1,381件のアラートを出し、そのうち1,331件が本物の問題でした。適合率は96.38%、再現率は94.06%、誤検知率は3.77%です。Pythonのベンチマーク(1,230件)では、誤検知率は3.47%でした。ベンチマークのページに、すべての件数と他のツールとの比較を掲載しています。これらの数値が測定しているのは検出のみであり、このベンチマークでは後述のサンドボックスでの検証は実行されていません。

到達可能性と悪用可能性

到達可能性は、攻撃者が制御できる入力が、指摘されたコードにそもそも到達できるかどうかを問います。これにより、デッドコードや、どこからも呼び出されない関数にある検出事項が除外されます。ただし、到達可能なコードでも安全な場合があります。入力が途中で検証されている可能性もあれば、危険な呼び出しが固定のリストの値しか受け取らない可能性もあります。

悪用可能性は、別の顧客のレコードを返す、サーバー上でコマンドを実行するなど、特定の入力が特定の有害な結果を生むかどうかを問います。これに確実に答える唯一の方法は、攻撃を実行することです。

検出事項を検証する方法

  1. 手動トリアージ。セキュリティエンジニアがコードを読んで判断します。正確ですが時間がかかり、ほとんどの小規模チームでは利用できません。
  2. 到達可能性解析。自動で高速ですが、到達可能で安全なものと、到達可能で悪用可能なものを区別できません。
  3. 実行中のアプリのテスト。動的スキャナーやペネトレーションテストは、デプロイされたアプリを外部から攻撃します。成功すれば説得力がありますが、デプロイされた環境が必要で、外部に露出しているものしか見えません。
  4. サンドボックス内の概念実証。使い捨てのコードのコピーに対して特定の攻撃を実行し、結果を観察します。これは自動で行われ、デプロイ前に実施されます。

Cyfendoが検出事項を検証する方法

  1. 追跡。Cyfendoは信頼できない入力をファイルをまたいでコード内で追跡し、入力が無害化されないままデータベースクエリ、ファイルパス、シェルコマンド、または他のユーザーのデータに到達する経路を指摘します。
  2. サンドボックス内での攻撃。指摘した経路ごとに概念実証の攻撃を作成し、使い捨てのアプリのコピーに対して実行します。外部サービスは代替のものに置き換えられます。Supabaseアプリには、プロジェクトのマイグレーションから構築された、2人のテストユーザーを持つ代替のSupabaseが用意されます。
  3. 無害なリクエストとの比較。攻撃が有害な結果を生み、かつ同じ経路の無害なリクエストが正常に動作しなければなりません。これにより、クラッシュやエラーページが証拠として扱われることを防ぎます。
  4. 報告。再現された問題は修正手順とともに報告されます。再現できなかった検出事項は、ダッシュボードに引き続き表示されます。
  5. 修正のテスト。パッチは、元の攻撃をパッチ適用後のコードに対して再実行し、プロジェクトのテストを実行することで確認されます。各パッチには、どのようにテストされたかが記載されます。

限界

  • 再現されなかった検出事項も、本物である可能性があります。攻撃によっては、本番環境の設定、サードパーティサービスの実際の動作、タイミングなど、サンドボックスでは再現されない要素に依存します。そのため、再現されなかった検出事項はダッシュボードに残ります。
  • コードが実行できる必要があります。検証は、言語のツールチェーンが利用できること、およびアプリが使うサービスの代替が用意されていることに依存します。
  • テストするのはコードであり、意図ではありません。ユーザーBがユーザーAのレコードを読み取れることは示せます。マネージャーが自分のチームのレコードを見てよいかどうかは、アプリの所有者だけが定義できるルールです。

Cyfendoは、リポジトリをスキャンする場合も、CLIから実行する場合も、Cursor、Claude Code、LovableなどのAIコーディングツールから呼び出される場合も、同じ方法で検出事項を検証します。

Cyfendoがコードから何を検出するかをご確認ください。

10,000行までのアプリは無料です。クレジットカードは不要です。