ブログに戻る

フォロー&ご登録

Fastly の WAF Simulator で WAF の検証テストを自動化

Simran Khalsa

Staff Security Researcher

Fastly Security Research Team

Fastly Security Research Team, Fastly

作成した Web アプリケーションファイアウォール (WAF) のルールが期待通りに機能するか気になりますか? その場合、どのように検証していますか? それともルールを作成して設定したら、もう気にしませんか? 時間が経ってもルールが想定通りに機能していることを、どのようにして保証できますか? チームメンバーがルールを変更した場合、それによって検出能力が損なわれる可能性がありますか? どのようにしてそれを確認することができますか?

Fastly の WAF Simulator にお任せください。この革新的な機能により、制御された安全なシミュレーション環境でルールを検証することが可能になります。WAF ルールを作成後、このシミュレーターを使用してルールが想定通りに機能していることを確認できます。異なるシステム間で切り替える必要がなく、サンプルリクエスト/レスポンスを提供するだけで、想定される WAF レスポンスとシグナルをシミュ―レーターが出力します。 

このブログ記事では、WAF Simulator を使用してルールを検証する方法に加えて、継続的に検証テストを実施するメリットについてご説明します。さらに、WAF Simulator を CI/CD パイプラインに統合して継続的な検証を自動化する方法を解説し、検証テストによって WAF に対して行われた変更を特定する例を分かりやすくご紹介します。

検証方法

Fastly のお客様は、管理コンソール内で WAF Simulator を使用してルールをテストして検証できます。サイトのルールを作成したら、Rules -> Simulator にアクセスしてリクエストとレスポンスのサンプルを入力し、Simulate をクリックします。シミュレーションが完了すると、WAF のレスポンスとシグナルが Simulation Output に表示されます。

以下は、機密性の高いアカウントの API エンドポイントリストのパスを含むリクエストを照合し、タグ付けするサイトルールがコンソールで検証されている様子を示しています。

ルールが想定通りに機能していることを確認したら、そのテスト設定を継続的な検証プロセスに応用させることが可能ですが、これについては後ほどご説明します。 

継続的に検証テストを実施するメリット

時間の経過と共に WAF ルールが古くなって本来の目的を果たさなくなったり、誤って設定されたりする可能性があり、これが正当なトラフィックのブロックや悪意のあるトラフィックの許可につながる誤検知を招きかねません。また、 WAF の設定に詳しい社員が退職した場合、設定や特定のルールの背後にある理論的根拠に関する重要な知識が失われるリスクがあります。さらに、多くの組織はコンプライアンス基準を遵守する必要があり、定期的な検証テストを実施することで、このような基準が満たされていることを確認しやすくなります。継続的な検証テストの実施によって、ルールが想定通りに機能していることを確認できるだけでなく、知識の移転を促進し、コンプライアンス基準を遵守しながらプロアクティなセキュリティ文化を育むことが可能になります。 

WAF Simulator を既存の CI/CD パイプラインに統合

継続的な検証テストを確立する方法のひとつに CI/CD パイプラインの使用があります。これを実証するため、Fastly の Next-Gen WAF (NG-WAF) を使用する2つの Web アプリケーション、app1.example.comapp2.example.com 向けの Terraform コードをホストする リポジトリの例を作成しました。これには、Fastly の WAF Simulator を使用する検証テストの自動化を促進する目的で Go で記述されたツールが含まれます。具体的には、メインブランチの各コード変更に対して検証テストを実行する GitHub Actions のワークフローを使用する CI/CD パイプラインを含めました。

検証テストの設定

検証テストは YAML 形式で記述され、test/rules のディレクトリに置かれています。YAML ファイルは、テストケースの定義と整理を構造化するのに役立ちます。各テストファイルにはテストのリストが含まれ、各テストには以下のフィールドが含まれます。

  • name : (必須) テストケースの固有識別子 

  • site : (必須) テスト対象として指定する Fastly NG-WAF のサイトの名前 

  • rule_id : (任意) テスト対象のルールの ID 

  • description : (任意) テストで確認したい内容に関する詳細

  • type : (任意) 真陽性、偽陰性、偽陽性、真陰性

  • request: (必須) テストの一部として送信される HTTP リクエスト

  • response: (必須) テストで想定されるレスポンス

  • expect: (必須) テストの予想結果の概要

    • waf_response: 想定される WAF からのレスポンスコード

    • signals : テストで返されるシグナルデータのリスト。各シグナルには複数の値が含まれ、空の場合は削除されます。 

      • type: シグナルの ID (= シグナルの種類) 

      • location: シグナル値 (「QUERYSTRING」や「USERAGENT」など) の場所

      • name: シグナルに割り当てられた名前

      • value: シグナルをトリガーする特定の値 

      • detector: シグナルを生成したディテクターの識別子

      • redaction: シグナル値が編集されているかどうかを示すバイナリ指標 (1または0)

以下はテストファイルの例です。

tests:
 - name: sensitive account api test 001
   site: app1.example.com
   rule_id: 63d04576d3b2e101d4f1345d
   description: tags request with site.sensitive-account-api
   type: true positive
   request: |
     POST /api/v1/account/update_profile HTTP/1.1
     Host: app1.example.com
     Content-Type: application/x-www-form-urlencoded
     Accept: */*
     User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_4)
     Content-Length: 8

     user=foo
   response: |
     HTTP/1.1 200 OK
   expect:
     waf_response: 200
     signals:
     - type: site.sensitive-account-api
       detector: 63e4404084fb8b01d40e3468

各テストファイルは解析され WAF Simulator に送信されます。スクリプトによって、シミュレートされた WAF のレスポンスとシグナルが、テストで定義された想定されるレスポンスとシグナルと比較されます。テストにパスしなかった場合、詳細が出力され、エラー回数に追加されます。 

使用開始方法

以下の手順に従ってください。

  1. https://github.com/fastly/waf-simulator-automation のリポジトリをクローンします。  

  2. NG-WAF の API キーを作成します。

    1. https://dashboard.signalsciences.net/login にアクセスして NG-WAF の管理コンソールにサインインします。 

    2. API Access Tokens にある My Profile タブで Add API access token を選択します。

    3. 名前を入力し、Create API access token を選択します。

  3. Fastly NG-WAF の認証情報を環境変数として設定します。 

    export SIGSCI_EMAIL='your-email'
    export SIGSCI_TOKEN='your-token'
    export SIGSCI_CORP='your-corp-id'
  4. Terraform がインストールされていない場合、こちらの手順に従ってインストールします。  

  5. プロジェクトディレクトリから terraform ディレクトリに移行して以下のコマンドを実行します。

    terraform init
    terraform plan -out ngwaf.plan
    terraform apply ngwaf.plan
  6. apply コマンドを実行したら、sensitive_account_api_rule_idinvalid_host_header_rule_id の出力値をメモします。 

  7. tests/rules/app1.example.com/sensitive-account-api.yaml を開き、65a190f3e3148001dc71a5ca の箇所をすべて、Terraform の出力に表示された sensitive_account_api_rule_id の値に置き換えます。

  8. tests/rules/app2.example.com/invalid-host-headers.yaml を開き、65a190f40f6eb201dc0fdd81 の箇所をすべて、Terraform の出力に表示された invalid_host_header_rule_id の値に置き換えます。

  9. テストファイルが更新されたら、WAF Simulator でテストを実行し、WAF ルールが正常に機能しているかどうかを検証できます。 

  10. Go がインストールされていない場合、こちらの手順に従ってインストールします。

  11. プロジェクトのルートディレクトリに戻り、以下のコマンドを実行します。

go run tests/main.go
  1. 失敗が確認されなかった場合、検証テストにパスしたことを意味します。失敗が確認されたら、ログを使用してトラブルシューティングを行い、問題を解決します。 

  2. こちらの手順に従って、GitHub に新しいディレクトリを作成します。

  3. リモート URL を新しいリポジトリに変更します。

git remote set-url origin https://github.com/yourusername/new-repository.git
  1. SIGSCI_EMAILSIGSCI_CORPSIGSCI_TOKENGitHub のシークレットに追加します。

  2. ワークフローファイルの .github/workflows/tests.yaml で、ブランチネームを main-branch から main に変更します。 

  3. 変更を追加してコミットします。

git add .github/workflows/tests.yaml
git commit -m "update workflow"
  1. 次に、git push コマンドを使用して新しいリポジトリにコードをプッシュします。

git push origin main
  1. プッシュしたら GitHub のリポジトリを確認し、テストワークフローが実行されていることを確かめます。

  2. リポジトリで ページトップの近くにある Actions タブにアクセスします。このタブには、リポジトリに関連するワークフロー実行のリストが表示されます。ここで、最近のワークフロー実行のリストを確認できます。各実行は、それをトリガーしたコミットまたはイベント (メインブランチへのプッシュなど) に関連付けられています。

  3. ワークフローが成功した場合、WAF ルールが想定通りに機能していることを意味します。

  4. 失敗が確認された場合、ログを使用してトラブルシューティングを行い、問題を解決します。修正後、変更を再度コミットしてプッシュし、ワークフローをトリガーします。

このコンセプトに基づいて Webhook 統合を設定し、ルールが修正されるたびにテストフローが自動的にトリガーされるようにすることができます。これは、管理コンソールを通じて行われた WAF ルールの変更が検出能力に悪影響を与えないようにするうえで便利です。 

シナリオ例

app2.example.com のために作成した invalid host header ルールを考えてみましょう。このルールは、安全に見える Web サーバー設定でも可能な HTTP ホストヘッダー攻撃を防ぐためのものです。以下のリストの値がホストヘッダーと完全に一致するか確認されます。ホストヘッダーがリストのどの値とも一致しない場合、ルールはリクエストをブロックし、site.invalid-host-header のシグナルを適用します。

www.app2.example.com
app2.example.com

私たちは不適切なホストヘッダーを含むリクエストを確実にブロックして適切にタグ付けするよう検証テストをセットアップしました。  

ここで、チームメンバーが新しいサブドメインの payments.app2.example.com を WAF に追加するシチュエーションを想像してみましょう。この更新後、ユーザーが payments.app2.example.com へのアクセスを試みると、「406 Not Acceptable」のレスポンスが返されるようになったとします。この問題を早急に解決するため、チームメンバーは WAF の管理コンソールにログインしてルールに変更を加え、リクエストをブロックするのではなく、許可するように切り替えたとします。 

この変更によりテストワークフローがトリガーされると、結果は失敗となります。テストではルールによってリクエストがブロックされることが想定されているにもかかわらず、現在は許可されているためです。チームメンバーは、すべてのリクエストを許可するのではなく、許可されたホストのリストに payments.app2.example.com を追加すべきでした。しかし、テストがセットアップされていたため、失敗の通知がチームの担当者に送信され、ルールを適切に調整できます。このフィードバックループがなければ、そのような変更に気づかず、「WAF は不適切なホストヘッダーを持つリクエストをブロックし続けている」という誤った思い込みにつながるでしょう。 

この例は、特に複数のスタッフが WAF を共同管理している場合に、テストを実施して WAF ルールの変更を特定することの重要性を浮き彫りにしています。継続的な検証テストの実施は、それなしでは気づかない変更を検出するうえで、重要な役割を担います。 

まとめ

この記事で取り上げた主なポイントを以下にまとめました。

  1. WAF Simulator を使用して WAF ルールを検証する方法

  2. 継続的に検証テストを実施するメリット

  3. WAF Simulator の CI/CD パイプラインへの統合 

  4. 検証テストによって NG-WAF への変更を特定する例

WAF の管理では、ルールの動作をテストして検証できる必要があります。継続的に検証テストを実施するアプローチとプラクティスによって、WAF ルールの有効性を維持できるだけでなく、ルールの背後にある理論的根拠を保持しながらコンプライアンス要件を遵守し、プロアクティブなセキュリティ文化を育むことが可能になります。