チュートリアルGitLab でのファズテストの実行

カバレッジガイドによるファズテストは、予期しない、不正な、あるいはランダムなデータをアプリケーションに送り、不安定な動作やクラッシュがないかアプリケーションを監視します。

これにより、他のQAプロセスでは見逃される可能性のあるバグや潜在的なセキュリティ問題を発見することができます。

ファズテストは、他のセキュリティスキャナや独自のテストプロセスに加えて使うべきです。GitLab CI/CDを使っているのであれば、CI/CDワークフローの一環としてファズテストを実行することができます。

このチュートリアルでは、JavaScript を使ってカバレッジガイドのファズテストを設定し、実行します:

  1. プロジェクトテンプレートをフォークして、ファズテストを実行するプロジェクトを作成します。
  2. ファズ・ターゲットを作成します。
  3. フォークしたプロジェクトでカバレッジガイドファズテストを有効にします。
  4. セキュリティの脆弱性を特定するために、ファズテストを実行してください。
  5. ファズ・テストによって特定された脆弱性を修正してください。

プロジェクトテンプレートのフォーク

まず、ファズテストを試すプロジェクトを作成するために、fuzz-testing プロジェクトテンプレートをフォークする必要があります:

  1. fuzz-testing プロジェクトテンプレート を開いてください。
  2. プロジェクト・テンプレートをフォークします。
  3. プロジェクトテンプレートをフォークする場合:

これでfuzz-testing プロジェクトテンプレートのフォークに成功しました。ファズテストを始める前に、プロジェクトテンプレートとフォークの関係を削除してください:

  1. 左サイドバーで、設定 > 一般を選択します。
  2. 詳細設定] を展開します。
  3. Remove fork relationshipセクションで、Remove fork relationshipを選択します。プロンプトが表示されたら、プロジェクト名を入力します。

プロジェクトの準備ができたので、ファズテストを作成することができます。次にファズ・ターゲットを作成します。

ファズ・ターゲットの作成

ファズテストのためのプロジェクトができたので、ファズターゲットを作成します。ファズターゲットは、入力が与えられたときに、テストされるアプリケーションに呼び出しを行う関数またはプログラムです。

このチュートリアルでは、ファズターゲットは、ランダムバッファをパラメータとして、my-tools.js ファイルの関数を呼び出します。

2つのファズ・ターゲット・ファイルを作成します:

  1. 左側のサイドバーで、[検索]を選択するか、 fuzz-testing-demo プロジェクトを検索します。
  2. プロジェクトのルート・ディレクトリにファイルを作成します。
  3. ファイル名を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 プロジェクトファイルからコピーすることもできます。

  4. ターゲットブランチに add-fuzz-test という名前をつけ、コミットメッセージを記述します。
    • これらの変更を含む新しいマージリクエストを開始するチェックボックスはまだ選択しないでください。
  5. 変更をコミット を選択します。
  6. プロジェクトのルートディレクトリに戻ります。
  7. add-fuzz-test ブランチにいることを確認してください。
  8. 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 プロジェクトファイルからコピーすることもできます。

  9. 説明的なコミットメッセージを書いてください。
  10. ターゲットブランチが add-fuzz-test であることを確認します。
  11. 変更をコミット を選択します。

これで、テスト対象のアプリケーションを呼び出すことができる 2 つのファズ・ターゲットができました。次にファズテストを有効にします。

カバレッジガイドファズテストの有効化

カバレッジガイドファズテストを有効にするには、gitlab-cov-fuzz CLIを実行するCI/CDパイプラインを作成し、2つのファズターゲットでファズテストを実行します。

パイプラインファイルを作成します:

  1. add-fuzz-test ブランチにいることを確認してください。
  2. fuzz-testing-demo プロジェクトのルート・ディレクトリに、新しいファイルを作成します。
  3. ファイル名を.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_targethello_fuzzing_target 。各ジョブはjsfuzz エンジンを使用して実行され、処理されなかった例外はクラッシュとしてレポーターされます。

    このコードはfuzz-testing-demo/fuzzers/fuzzers.yml プロジェクトファイルからコピーすることもできます。

  4. 説明的なコミットメッセージを書いてください。
  5. ターゲットブランチが add-fuzz-test であることを確認します。
  6. 変更をコミット を選択します。

これでカバレッジガイドファズテストが有効になりました。次に、作成したパイプラインを使ってファズテストを実行します。

ファズテストの実行

ファズテストを実行するには

  1. 左サイドバーで、コード > マージリクエストを選択します。
  2. 新しいマージリクエストを選択します。
  3. ソースブランチセクションで、add-fuzz-test ブランチを選択します。
  4. ターゲット・ブランチ・セクションで、ネームスペースとmain ブランチが選択されていることを確認します。
  5. ブランチを比較して続行を選択します。
  6. マージリクエストを作成します。

マージリクエストを作成すると、新しいパイプラインが起動され、ファズテストが実行されます。パイプラインの実行が終了すると、マージリクエストページにセキュリティ脆弱性の警告が表示されます。

それぞれの脆弱性の詳細情報を見るには、個々のUncaught-exceptionリンクを選択してください。

ファズテストの実行に成功し、修正すべき脆弱性が特定されました。

脆弱性の修正

ファズ・テストは2つのセキュリティ脆弱性を特定しました。これらの脆弱性を修正するために、my-tools.js ライブラリを使用します。

my-tools.js

  1. プロジェクトのadd-fuzz-test ブランチにいることを確認してください。
  2. プロジェクトのルート・ディレクトリに移動し、my-tools.js ファイルを開きます。
  3. このファイルの内容を以下のコードに置き換えてください:

    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 プロジェクト・ファイルからコードをコピーすることもできます。

  4. 変更をコミットするを選択します。これにより、別のパイプラインがトリガーされ、別のファズテストが実行されます。
  5. パイプラインが終了したら、マージリクエストの概要ページを確認してください。セキュリティスキャンによって、新たな脆弱性が検出されなかったことがわかるはずです。
  6. 変更をマージしてください。

おめでとうございます。ファズテストに成功し、特定されたセキュリティ脆弱性を修正できました!

詳細については、カバレッジガイドファズテストを参照してください。