【翻訳】ZAP を用いた Web セキュリティのベースライン運用
この記事は、2017 年 1 月 25 日付で Mozilla Security Blog に投稿された Setting a Baseline for Web Security Controls(筆者: Simon Bennetts)の翻訳です。この翻訳は公式なものではありません。詳しくはこちらをご覧ください。
モダンな web アプリケーションの開発において、安全性を効果的に高める施策は複雑となりがちです。とはいえ、web の世界で広く知られている攻撃を防ぐためならば、セキュリティ目的の各種 HTTP ヘッダなど、防御策として有効かつシンプルなセキュリティ機能は数多くあります。
Mozilla では Firefox 関連サービスの開発者向けに、セキュリティ機能に関する セキュリティガイドライン と チェックリスト を策定しています。昨年は web サイト・サービスの安全性評価を目的とし、ホスト型のスキャナである Mozilla Observatory を導入しました。今回のブログ記事では、継続的インテグレーションと継続的デプロイメント(CI/CD)の環境において、web アプリケーションのセキュリティテストを、ZAP のベースラインスキャンで行う手法について解説します。
アプリケーション全体でセキュリティ機能が正しく設定されているかを確認するのは、特に CI/CD 環境では困難となり得ます。私たちの環境では、サービスの脆弱性に対するフルスキャンを定期的に実行していますが、スキャンの終了までに長時間を要したり、ペースの速いリリースサイクルと相性が悪いなどの問題点があります。
こうした背景に基づき、サービスのリリース毎に実行できる程度に高速で、かつセキュリティ機能に関する重要なフィードバックを返す、「ベースライン(最低限)」のスキャン手法を導入しました。ベースラインスキャンは Firefox サービスの CI/CD プロセスに組み込まれており、プロダクション環境へ移行する前に、サービスに潜んでいる問題を開発者へ通知する仕組みとなっています。このスキャンは各サービスに対して毎日行われ、セキュリティに対するサービス全体の状況を示したダッシュボードが作成されます。
今回のブログ記事では、私たちの開発インフラにベースラインスキャンを取り入れた際の、技術的な詳細について説明します。
ZAP Baseline Scan
Mozilla はセキュリティツールの開発・サポートへ積極的に投資しています。この記事を書いている筆者は OWASP Zed Attack Proxy (ZAP) プロジェクトのリーダーですが、今回説明する脆弱性のベースラインスキャンには ZAP を使用しています。
ZAP Baseline scan は高速・簡単かつカスタマイズ性の高いセキュリティテストツールです。プロダクションのアプリケーションに対して安全に実行できるよう、このツールには侵入テストは含まれていません。
zap-baseline.py のスクリプトを走らせるには、ZAP をインストールしておく必要はなく、Docker と以下 2 つの ZAP Docker イメージを用意すれば十分です。
私たちのベースラインスキャンでは、より多くのオプションを持つ weekly の Docker イメージを使用しています。指定できるオプションの一覧は、スクリプトに -h フラグを付けると確認できます。
zap-baseline.py のスクリプトは、アプリケーションのスキャン時に ZAP のスパイダー検索を実行しますが、デフォルト設定における所要時間はわずか 1 分です。アプリケーションへのスパイダー検索が重要なのは、トップページのみならず、すべてのページに対して必要なセキュリティ機能の実装状況を確認できる点にあります。このスキャンは特に、web フレームワークが一部のページでヘッダを設定していないケースの発見に役立ちます。潜んでいた問題点のうち発見できたものは、その後スクリプトによってすべて報告されます。
アプリケーションに対するベースラインスキャンは -t フラグに URL を指定するだけで実行できます。以下に例を示します。
docker run owasp/zap2docker-weekly zap-baseline.py -t https://www.example.com
実行すると以下のような出力が得られます。
Total of 3 URLs PASS: Cookie No HttpOnly Flag [10010] PASS: Cookie Without Secure Flag [10011] PASS: Password Autocomplete in Browser [10012] PASS: Cross-Domain JavaScript Source File Inclusion [10017] PASS: Content-Type Header Missing [10019] PASS: Information Disclosure - Debug Error Messages [10023] PASS: Information Disclosure - Sensitive Informations in URL [10024] PASS: Information Disclosure - Sensitive Information in HTTP Referrer Header [10025] PASS: HTTP Parameter Override [10026] PASS: Information Disclosure - Suspicious Comments [10027] PASS: Viewstate Scanner [10032] PASS: Secure Pages Include Mixed Content [10040] PASS: Weak Authentication Method [10105] PASS: Absence of Anti-CSRF Tokens [10202] PASS: Private IP Disclosure [2] PASS: Session ID in URL Rewrite [3] PASS: Script Passive Scan Rules [50001] PASS: Insecure JSF ViewState [90001] PASS: Charset Mismatch [90011] PASS: Application Error Disclosure [90022] PASS: WSDL File Passive Scanner [90030] PASS: Loosely Scoped Cookie [90033] WARN: Incomplete or No Cache-control and Pragma HTTP Header Set [10015] x 1 https://www.example.com WARN: Web Browser XSS Protection Not Enabled [10016] x 3 https://www.example.com https://www.example.com/robots.txt https://www.example.com/sitemap.xml WARN: X-Frame-Options Header Not Set [10020] x 1 https://www.example.com WARN: X-Content-Type-Options Header Missing [10021] x 1 https://www.example.com FAIL-NEW: 0 FAIL-INPROG: 0 WARN-NEW: 4 WARN-INPROG: 0 INFO: 0 IGNORE: 0 PASS: 22
デフォルト設定の場合、実施された非侵入スキャンの内容と結果が一覧表示されます。
ベースラインスキャンにおけるエラーの扱い方を変更するには、そのルールを指定したファイルを -c フラグ(ローカルファイルの場合)または -u フラグ(リモートの URL の場合)で指定します。なお、デフォルトルールのファイルは ‘g’ オプションで生成できます。https://github.com/zaproxy/community-scripts/blob/master/api/mass-baseline/mass-baseline-default.conf 生成されたファイルの各ヘッダで指定されているように、"WARN" の箇所を “IGNORE” や “FAIL” に変更できます。
スクリプトの終了コードは、何も問題が無かった場合は 0、いずれかのテストに失敗した場合は 1、警告のみの場合は 2 となっています。そのため、Jenkins や CircleCI、TravisCI などの CI ツールにおいて、ビルドプロセスを中止させたい場合この戻り値を利用できます。
例えば、各プルリクエストごとにベースラインスキャンを実行させる CircleCI の設定は以下のようになります。
test: override: # build and run an application container - docker build -t myrepo/myapp - docker run myrepo/myapp & # retrieve the ZAP container - docker pull owasp/zap2docker-weekly # run the baseline scan against the application - | docker run -t owasp/zap2docker-weekly zap-baseline.py \ -t http://172.17.0.2:8080/ -m 3 -i
複数サイトのスキャン
Baseline scan は、単一のサイトが最低限のセキュリティ要件を満たしているか確認するのに有効なツールです。
多数の web サイトに ZAP Baseline scan を実行させるため、私たちは Mozilla 用のラッパースクリプトを書きました。これらのスクリプトを汎用化したものは ZAP community-scripts のリポジトリ で参照できます。
README で詳しく書かれている通り、実際に使用する際はスクリプトのカスタマイズが必要となります。
- mass-baseline.sh でサイトを指定している箇所を変更
- mass-baseline.sh の user と repo を適切に変更
- Docker イメージのビルド
- Docker イメージを起動し、ユーザの資格情報を設定
以上のスクリプトを走らせると、repo で指定したリポジトリの wiki にサマリのダッシュボードが作成されます。
‘Status’ 欄のバッジは、対応するアプリケーションに対して最後に実行した、ベースラインスキャンの結果へリンクしています。また ‘History’ 欄の日付は、過去に実施したスキャン結果をすべて確認できるページへリンクしています。作成されるダッシュボードの例は community-scripts の wiki ページで参照できます。https://github.com/zaproxy/community-scripts/wiki/Baseline-Summary
カスタマイズ
Baseline scan はカスタマイズ性が高いので、アプリケーションをより効果的にスキャンするために、以下のような詳細な設定が可能です。
- アプリケーションへのスパイダー検索にかける時間を増やす
- JavaScript を大量に使用しているアプリケーションに対して、ZAP の通常のスパイダー検索に加えて Ajax スパイダー検索を使用する
- 非侵入スキャンのルールを release quality(デフォルト値)のみならず、alpha や beta のルールも含める
- 既知の問題についてバグトラッカーの URL へリンクさせる
- コマンドライン版の ZAP でサポートされているオプションを指定する
詳細は ZAP の wiki を参照してください。https://github.com/zaproxy/zaproxy/wiki/ZAP-Baseline-Scan
まとめ
Baseline scan により、web アプリケーション全体にわたってセキュリティ機能の実装状況を素早く確認できます。リグレッションを即座に検知するため、コミットごとにスキャンを実行するユースケースも考えられます。ダッシュボードを利用すればアプリケーションの状態を追跡することができ、CI との連携によりベースラインを満たさないデプロイを防ぐことも可能です。
ベースラインスキャンを CI/CD 環境に取り入れることで、開発者と運用者がより密接に協力できるようになります。私たちはセキュリティツールの使用を DevOps のプロセスに強制するのではなく、セキュリティを DevOps に取り入れる形をとっています。その結果、チーム間に協力関係が生まれ、セキュリティ問題の修正によって状況が素早く改善されるといった利点が得られます。