こんにちは。SIGQ Cloud Linkerというセキュアな書類共有サービスを開発しているアーリースタートアップ、SIGQのリードエンジニアをしているBrown[1-2]です。
SIGQではDatadogのBrowser Testingを使用して、ブラウザ上で重要な機能が適切に動作するかの検証を自動で行っています。
Datadogに限らず、他社のBrowser Testingも含め、これらは非常に有用なツールである一方で、ログインの認証が求められたり、WAFなどのセキュリティレイヤーを導入していると、公式ドキュメント通りに設定しても、様々な原因でちゃんと動かないことがあります。 本日はDatadogのBrowser TestingをWAF(Web Application Firewall)が入っているWebサービスに導入する際の困ったことと、解決方法を共有します。
DatadogのBrowser Testingとは
Datadogのブラウザテストは、ウェブアプリケーションのユーザーの行動をシミュレートし、定期的にその動作を検証する機能です。これにより、アプリケーションの可用性やパフォーマンスを継続的に監視し、ユーザーが遭遇する可能性のある問題を早期に検出できます。
主な特徴
シナリオベースのテスト: DatadogのRUM (Real User Monitoring)でユーザーの操作手順を記録し、複雑なシナリオを自動化して再現できます。
多様な環境での実行: 異なるブラウザやデバイス、地理的なロケーションからテストを実行し、さまざまなユーザー環境での動作を確認できます。
WAF導入環境でDatadogを導入すると困ること
SIGQではWAFにCloudflareの有料版WAFを導入して、より安全なアプリケーションをご提供できるようにしています。
Cloudflare WAFではBot managementの機能がついているため、Botっぽいリクエストを弾く設定を行うことができますが、一方で、この設定によりDatadogのBrowser Testingからサイトにアクセスした時に弾かれてしまうことがあります。ちゃんとWAFが機能してるのでヨシッとはできず、Browser Testingの観点では困った問題で、もしかしたらこのブログに辿り着いた方は「よくわかんないからBrowser Testingを入れるのを諦めようかな。。。」となっておられる方もいるのではないでしょうか。
実際にDatadogのBrowser TestingがCloudflare WAFに弾かれた図
/(^o^)\ナンテコッタイ
WAFにBrowser TestingがBlockされるのを防ぐ方法
SIGQではFirebase Hostingをオリジンにして、WAFとDNSだけCloudflareを使用しています。そのため、WAFにブロックされるのを防ぐためには、以下の2つの方法が挙げられます。
特定のリクエストヘッダーがある場合のみCloudflareのWAFポリシーをIgnoreする設定を入れる
特定のパスだけCloudflareのWAFポリシーをIgnoreする設定を入れる
Browser TestingからはFirebase Hosting のURLを直指定してWAFを通さないようにする
今回取ったワークアラウンド
今回は1の「特定のリクエストだけCloudflareのWAFポリシーをIgnoreする設定を入れる」という設定をCloudflare側で設定しました。具体的にはリクエストヘッダーに特定のキーがセットされていれば、そのリクエストはWAFを適用しないという方法です。
CloudflareでのWAF設定
このルールは「すべてのリクエストにWAFのルールを適用するが、リクエストヘッダーに特定のキーがセットされていれば、そのリクエストは無視する」という方法です。
後述しますが、この方法では折角WAFを導入しているのに、その例外でWAFのルールが適用されないリクエストヘッダーを無闇に外部に公開すると、そのリクエストヘッダーを悪意のある攻撃者がセットしてリクエストしてきた際にWAFで防げないので、以下のスクショではマスクしています。
Datadogでの設定
Browser Testingの「Advanced Options」から、先ほどcloudflareでセットしたキーをリクエストヘッダーにセットします。
今回取ったワークアラウンドの理由
まず、このてのワークアラウンドを入れる際には、サービスに悪い副作用を極力及ぼさないようにする必要があります。例えば、Browser Testingでサービスの信頼性を向上させようとした結果、うまく動かなかったワークアラウンドでアプリケーションコードのCORSの設定をザルにしたりしてセキュリティホールを開けては本末転倒です。
そこで本提案手法では「リクエストヘッダーに特定のキーがセットされていれば、そのリクエストは無視する」というWAFの設定を入れました。この方法では、アプリケーションコードを変更する必要がなく、WAF側の設定だけを変更するだけであり、かつ、そのヘッダーがあってもなくても、アプリケーションの動作自体には影響が出ないので、アプリケーションに変な副作用は及ぼしにくいです。
ここで、前述した「そのリクエストヘッダーを悪意のある攻撃者がセットしてリクエストしてきた際にWAFで防げない」という点は副作用としてあげられますが、このリクエストヘッダーはパブリックな場に貼るものでもないので、外に漏れにくいです。また、定期的にローテートするようにすれば、リスクは軽減できると思っています。
他の選択肢
次に、他の選択肢に関して見ていきます。
特定のパスだけCloudflareのWAFポリシーをIgnoreする設定を入れる
この場合には、そのパスだけWAFのポリシーがかからなくなるので、そのパスがBotによる攻撃を受けた時に、他のパスに比べて脆弱になりかねません。また、他のパスをテストしたい時には都度パスを加える必要があるので、煩雑です。
Browser TestingからはFirebase Hosting のURLを直指定してWAFを通さないようにする
前提として、特定のドメインからのリクエストのみをバックエンドサーバーのCORSのAllowOriginの設定では許可するようにしていますが、この方法では、Firebase HostingのURLをブラウザテストのためだけにCORSの設定に追加しなければなりません。つまり、本来CORSのAllowOriginで特定のドメインからのアクセスだけにしたいのに、テストのためだけに他のドメインもCORSのAllowOriginに加えないといけないため、微妙です。
最後に
SIGQではCloud Linker (https://sigq.jp/)を使っていただける方を絶賛募集中です。 まだパブリックには新規登録導線を開けていませんが、利用ご希望の方はぜひプロダクトページの右下からサポートチケットを起票いただいて、利用希望の旨を教えてください。アーリーサインアップ特典で、何らか特典をご用意したいと思っています。(詳細未定)
References
[1] あちこちの組織に属しており、インターネット上で筆者関連情報が散見されるが、本法人とはいずれも無関係
[2] GitHub Account: https://github.com/3150