Skip to content
Latchkey

ファズテストとは?

ファズテストは、大量のランダム、不正、または予期しない入力をプログラムに投げつけ、クラッシュ、ハング、セキュリティ上の欠陥を見つけます。

ファズテスト(ファジング)とは、コードにゴミのような入力を浴びせて何が壊れるかを見る手法です。プロパティベーステストが論理的な性質を検証するのに対し、ファジングは主にプログラムをクラッシュ、ハング、または誤動作させる入力を探します。パーサー、デコーダー、そして信頼できないデータを扱うあらゆるもののセキュリティテストにおける定番です。

ファジングの仕組み

ファザーはターゲットに生成した入力のストリームを与え、悪い結果を監視します: クラッシュ、メモリエラー、無限ループ、アサーション失敗などです。興味深い失敗はそれぞれ再現可能なケースとして保存されます。試す入力が多いほど、エッジケースの奥深くまで到達します。

カバレッジガイド型ファジング

現代のファザーはカバレッジガイド型です: コードをインストルメント化し、新しいコードパスに到達する入力を優先し、プログラムのより多くの部分を実行する入力へと進化させます。これにより、盲目的なランダム入力よりもはるかに効果的に深いバグを見つけられます。

簡単な例

ファズターゲットは任意のバイト列をパーサーに渡します。パーサーが本来グレースフルに拒否すべき入力でクラッシュした場合、ハーネスは失敗します。

A Go fuzz target
func FuzzParse(f *testing.F) {
  f.Fuzz(func(t *testing.T, data []byte) {
    Parse(data) // must not panic
  })
}

ファジングが効果を発揮する場面

  • パーサー、デコーダー、シリアライザー。
  • 信頼できない外部入力を処理するあらゆるもの。
  • セキュリティに敏感なコードパス。
  • 例では決してトリガーされないクラッシュの発見。

CI でのファジング

ファジングには終わりがないため、チームは通常、各 pull request で短いファズパスを実行し、より長い継続的ファジングをスケジュールで実行します。どちらも高速な runner での並列実行の恩恵を受けます。計算リソースが多いほど、より多くの入力が試され、1 時間あたりに見つかるバグも増えるからです。

重要なポイント

  • ファズテストはランダムまたは不正な入力を与えてクラッシュや欠陥を見つけます。
  • カバレッジガイド型のファザーは、新しいコードパスに向けて入力を進化させます。
  • PR ごとに短いファジングを、CI では長いスケジュール実行のファジングを行いましょう。

関連ガイド