GitLabは、13.4リリースで導入されたCore Prototol Fuzz Testingエンジンを、オープンソースとして公開した。ファズテスト(Fuzz Tesiting)とは、ランダムに生成された入力をアプリにわたすことで、ビジネスロジック内にあるセキュリティ上の問題や欠陥をより効率的に見つけ出すことを目的とするものだ。
GitLabがファズテストを導入したのは昨年末、Peach TechとFuzz itを買収した直後のことだった。
GitLabのAPIファズテストでは、Open API v2仕様またはアプリケーションのHAIRファイルを指定することによって、エッジケースを実行するように設計されたランダムな入力を自動生成して、バグを検出する。実行結果はパイプラインの一部として、即時表示される。
Protocolファズテストは、すでにGitLabに組み込まれているこのファズ機能を、ネットワークプロトコルやファイルフォーマットのファズテストが可能なように拡張したものだ。
同社Principal Product ManagerのSam Kerr氏に詳しい話を聞いた。
InfoQ: ファズテストとは何なのか、なぜ多くのソフトウェア企業が関心を持っているのか、簡単に説明して頂けますか?
Kerr: ファズテストは、他のテクニックでは見落としてしまうようなバグや脆弱性を見つけ出すための手段です。ランダムな入力を生成してクラッシュを発生させ、それまでテストされていなかったアプリケーションの部分を見つけることで、これを実現します。前もって決定されたシグネチャやパターンではなく、ランダムに生成された入力を用いることで、テスト用に記述したシグネチャではできないような、アプリのビジネスロジックに固有の問題を見つけることが可能になります。
すでに実施されているテストやセキュリティスキャンを補完する優れた手段として、ファズテストは、ますます多くの企業の注目を集めています。ファズテストによって見つけることのできる問題は、他のテクニックを使ってできるものとは違います。ですから、他のテストやセキュリティメソッドを置き換えるのではなく、補完するものなのです。
アプリのタイプやユースケースによって、使用可能なファズテストにはいくつかのタイプがあります。GitLabのプロダクトでは現在、Coverage-guidedファズテストとAPIファズテストという、2つのタイプのファズテストを使用することができます。それぞれがアプリケーションとそのコードを、"インサイド・アウト"および"アウトサイド・イン"にテストするものです。今回の新しいオープンソースリポジトリでは、プロトコルのファズテスト手段をコミュニティに提供することによって、TCPのような低レベルのネットワークプロトコルや、JPGなどのファイルフォーマットのテストを可能にします。
InfoQ: ファズテストをCIパイプラインに組み込もうとする場合、どのようなことが問題になるのでしょうか?
Kerr: ファズテストのおもな問題のひとつは、使用やセットアップが難しいと思われていることです。GitLabでは、ユーザがセキュリティのエキスパートにならなくても、バグや脆弱性を簡単に見つけられるようにするために、ユーザビリティを重点な領域のひとつにしています。プロトコルのファズテストでも今後、これと同じアプローチを採用する予定です。
ファズテストを行う上で必要なもうひとつのステップは、問題を検出するのに十分なテスト時間と開発者による対応時間とのバランスを考慮して、テストの実施時間を決定することです。一般的には、コードのコミット毎に短時間のファズジョブを実行して、アプリケーションのリリース時に長時間のファズジョブを実行しているようです。この方法であれば、開発者の作業をスローダウンすることなく、可能な限り多くの問題を発見するという、よいバランスが実現できます。
InfoQ: GitLab Protocol Fuzzer Community Editionは誰を対象に、どのようなファズテストの導入支援を行うものなのでしょうか?
Kerr: GitLab Protocol Fuzzer Community Editionはオープンソースなので、誰でもコントリビューションが可能です。今回のリリースでは、GitLabがPeachTechから取得したコアエンジンの部品が多数提供されているので、ユーザ自身のプロトコルのサポートを構築することができます。ファズテストに習熟したセキュリティ研究者やユーザがこのリポジトリを使用してプロトコルを構築したり、コアエンジンに必要と思われる機能を提供してくれることを期待しています。以前のPeach Fuzzer Community Editionを使用しているユーザならば、新しいGitLab Protocol Fuzzer Community Editionをすぐに使い始められると思います。
将来的には、ビルド済のプロトコルをいくつか提供して、ファズテストに不慣れなユーザにも簡単に導入できるようにしていきたいと考えています。
InfoQ: GitLab Protocol Fuzzer Community Editionが他のファズテスト製品と異なるのは、どのような部分なのでしょうか?
Kerr: GitLabは現在、Coverage-guidedファズテストとAPIファズテストの2つを提供しています。これらはいずれも、プロトコルファズテストとはユースケースが違います。
前者はアプリ全体、あるいはアプリのテスト対象部分の周りに小さな"テストハーネス"を設置するものです。このハーネスがアプリを監視すると同時に、インテリジェントにテストを変更しながら実行して、結果を求めます。この方法は、数多く用意されたサポート対象言語のいずれかで記述されたものであれば、Web、デスクトップ、サーバなどさまざまなアプリで使用可能です。
後者はAPIの定義、あるいはAPIにおけるインタラクションの記録を使用して、アプリが期待する情報のタイプをファザー(Fuzzer)に指示します。OpenAPI仕様、HARレコーディング、Postmanコレクションなどが使用可能です。APIファザーはこれらの情報を使ってランダムな値を生成し、APIのバグを検出するのです。この方法は、HTTP上でAPIを公開しているアプリで特に有効です。
プロトコルファズテストはこれらとは違い、低レベルのプロトコルやアプリの使用するファイルフォーマットをテストするものです。プロトコルファザーは使用するプロトコルの定義を与えられると、有効なプロトコルメッセージをインテリジェントに変化させて、アプリのプロトコル実装内のバグを検出します。例えば、プロトコルメッセージに長さが値としてサポートされている場合には、不正な長さを値として与えて、アプリがそれを適切に処理できるか確認します。このテストは、オペレーティングシステムが提供するものではなく、独自に実装したプロトコルを使用する場合の多い、組み込みデバイスや低レベルのソフトウェアでは特に重要です。
もうひとつの違いは、GitLab Protocol Fuzzer Community EditionはGitLabがホストとメンテナンスを行うオープンソースプロジェクトですが、GitLabのプロダクトにはまだ統合されていない、という点です。このため、ユーザがソースコードを見たり、変更したり、ローカルで実行したり、自身のパイプラインに加えたりすることが可能です。一方、Coverage-guidedファズテストとAPIファズテストはいずれもGitLabプロダクトの一部であり、緊密に統合されているので、実行結果はSecurity Dashboardや開発者のマージ要求に現れるようになります。将来的にはGitLab Protocol Fuzzer Community Editionを拡張してGitLabに統合し、他のユーザにも同様のエクスペリエンスを提供したいと考えています。
GitLabの最新バージョンであるGitLab 13.10では、OpenAPI v3のサポートやファズテストの設定を容易にする新UIなど、ファズテストに関する多数の改良が加えられている。