チュートリアルGitLab でのファズテストの実行
カバレッジガイドによるファズテストは、予期しない、不正な、あるいはランダムなデータをアプリケーションに送り、不安定な動作やクラッシュがないかアプリケーションを監視します。
これにより、他のQAプロセスでは見逃される可能性のあるバグや潜在的なセキュリティ問題を発見することができます。
ファズテストは、他のセキュリティスキャナや独自のテストプロセスに加えて使うべきです。GitLab CI/CDを使っているのであれば、CI/CDワークフローの一環としてファズテストを実行することができます。
このチュートリアルでは、JavaScript を使ってカバレッジガイドのファズテストを設定し、実行します:
- プロジェクトテンプレートをフォークして、ファズテストを実行するプロジェクトを作成します。
- ファズ・ターゲットを作成します。
- フォークしたプロジェクトでカバレッジガイドファズテストを有効にします。
- セキュリティの脆弱性を特定するために、ファズテストを実行してください。
- ファズ・テストによって特定された脆弱性を修正してください。
プロジェクトテンプレートのフォーク
まず、ファズテストを試すプロジェクトを作成するために、fuzz-testing
プロジェクトテンプレートをフォークする必要があります:
-
fuzz-testing
プロジェクトテンプレート を開いてください。 - プロジェクト・テンプレートをフォークします。
- プロジェクトテンプレートをフォークする場合:
これでfuzz-testing
プロジェクトテンプレートのフォークに成功しました。ファズテストを始める前に、プロジェクトテンプレートとフォークの関係を削除してください:
- 左サイドバーで、設定 > 一般を選択します。
- 詳細設定] を展開します。
- Remove fork relationshipセクションで、Remove fork relationshipを選択します。プロンプトが表示されたら、プロジェクト名を入力します。
プロジェクトの準備ができたので、ファズテストを作成することができます。次にファズ・ターゲットを作成します。
ファズ・ターゲットの作成
ファズテストのためのプロジェクトができたので、ファズターゲットを作成します。ファズターゲットは、入力が与えられたときに、テストされるアプリケーションに呼び出しを行う関数またはプログラムです。
このチュートリアルでは、ファズターゲットは、ランダムバッファをパラメータとして、my-tools.js
ファイルの関数を呼び出します。
2つのファズ・ターゲット・ファイルを作成します:
- 左側のサイドバーで、[検索]を選択するか、
fuzz-testing-demo
プロジェクトを検索します。 - プロジェクトのルート・ディレクトリにファイルを作成します。
-
ファイル名を
fuzz-sayhello.js
とし、以下のコードを追加します:let tools = require('./my-tools') function fuzz(buf) { const text = buf.toString() tools.sayHello(text) } module.exports = { fuzz }
このコードは
fuzz-testing-demo/fuzzers/fuzz-sayhello.js
プロジェクトファイルからコピーすることもできます。 -
ターゲットブランチに
add-fuzz-test
という名前をつけ、コミットメッセージを記述します。- これらの変更を含む新しいマージリクエストを開始するチェックボックスはまだ選択しないでください。
- 変更をコミット を選択します。
- プロジェクトのルートディレクトリに戻ります。
-
add-fuzz-test
ブランチにいることを確認してください。 -
fuzz-readme.js
という名前の2番目のファイルを作成し、以下のコードを追加します:let tools = require('./my-tools') function fuzz(buf) { const text = buf.toString() tools.readmeContent(text) } module.exports = { fuzz }
このコードは
fuzz-testing-demo/fuzzers/fuzz-readme.js
プロジェクトファイルからコピーすることもできます。 - 説明的なコミットメッセージを書いてください。
-
ターゲットブランチが
add-fuzz-test
であることを確認します。 - 変更をコミット を選択します。
これで、テスト対象のアプリケーションを呼び出すことができる 2 つのファズ・ターゲットができました。次にファズテストを有効にします。
カバレッジガイドファズテストの有効化
カバレッジガイドファズテストを有効にするには、gitlab-cov-fuzz
CLIを実行するCI/CDパイプラインを作成し、2つのファズターゲットでファズテストを実行します。
パイプラインファイルを作成します:
-
add-fuzz-test
ブランチにいることを確認してください。 -
fuzz-testing-demo
プロジェクトのルート・ディレクトリに、新しいファイルを作成します。 -
ファイル名を
.gitlab-ci.yml
とし、以下のコードを追加します:image: node:18 stages: - fuzz include: - template: Coverage-Fuzzing.gitlab-ci.yml readme_fuzz_target: extends: .fuzz_base tags: [saas-linux-large-amd64] # Optional variables: COVFUZZ_ADDITIONAL_ARGS: '--fuzzTime=60' script: - npm config set @gitlab-org:registry https://gitlab.com/api/v4/packages/npm/ && npm i -g @gitlab-org/jsfuzz - ./gitlab-cov-fuzz run --engine jsfuzz -- fuzz-readme.js hello_fuzzing_target: extends: .fuzz_base tags: [saas-linux-large-amd64] # Optional variables: COVFUZZ_ADDITIONAL_ARGS: '--fuzzTime=60' script: - npm config set @gitlab-org:registry https://gitlab.com/api/v4/packages/npm/ && npm i -g @gitlab-org/jsfuzz - ./gitlab-cov-fuzz run --engine jsfuzz -- fuzz-sayhello.js
このステップでは、パイプラインに以下を追加します: - テンプレートを使用した
fuzz
ステージ。 - 2つのジョブ、readme_fuzz_target
とhello_fuzzing_target
。各ジョブはjsfuzz
エンジンを使用して実行され、処理されなかった例外はクラッシュとしてレポーターされます。このコードは
fuzz-testing-demo/fuzzers/fuzzers.yml
プロジェクトファイルからコピーすることもできます。 - 説明的なコミットメッセージを書いてください。
-
ターゲットブランチが
add-fuzz-test
であることを確認します。 - 変更をコミット を選択します。
これでカバレッジガイドファズテストが有効になりました。次に、作成したパイプラインを使ってファズテストを実行します。
ファズテストの実行
ファズテストを実行するには
- 左サイドバーで、コード > マージリクエストを選択します。
- 新しいマージリクエストを選択します。
-
ソースブランチセクションで、
add-fuzz-test
ブランチを選択します。 -
ターゲット・ブランチ・セクションで、ネームスペースと
main
ブランチが選択されていることを確認します。 - ブランチを比較して続行を選択します。
- マージリクエストを作成します。
マージリクエストを作成すると、新しいパイプラインが起動され、ファズテストが実行されます。パイプラインの実行が終了すると、マージリクエストページにセキュリティ脆弱性の警告が表示されます。
それぞれの脆弱性の詳細情報を見るには、個々のUncaught-exceptionリンクを選択してください。
ファズテストの実行に成功し、修正すべき脆弱性が特定されました。
脆弱性の修正
ファズ・テストは2つのセキュリティ脆弱性を特定しました。これらの脆弱性を修正するために、my-tools.js
ライブラリを使用します。
my-tools.js
:
- プロジェクトの
add-fuzz-test
ブランチにいることを確認してください。 - プロジェクトのルート・ディレクトリに移動し、
my-tools.js
ファイルを開きます。 -
このファイルの内容を以下のコードに置き換えてください:
const fs = require('fs') function sayHello(name) { if(name.includes("z")) { //throw new Error("😡 error name: " + name) console.log("😡 error name: " + name) } else { return "😀 hello " + name } } function readmeContent(name) { let fileName = name => { if(name.includes("w")) { return "./README.txt" } else { return "./README.md" } } //const data = fs.readFileSync(fileName(name), 'utf8') try { const data = fs.readFileSync(fileName(name), 'utf8') return data } catch (err) { console.error(err.message) return "" } } module.exports = { sayHello, readmeContent }
fuzz-testing-demo/javascript/my-tools.js
プロジェクト・ファイルからコードをコピーすることもできます。 - 変更をコミットするを選択します。これにより、別のパイプラインがトリガーされ、別のファズテストが実行されます。
- パイプラインが終了したら、マージリクエストの概要ページを確認してください。セキュリティスキャンによって、新たな脆弱性が検出されなかったことがわかるはずです。
- 変更をマージしてください。
おめでとうございます。ファズテストに成功し、特定されたセキュリティ脆弱性を修正できました!
詳細については、カバレッジガイドファズテストを参照してください。