DevSecOpsを加速、OWASP ZAP×DVWAで学ぶ動的アプリケーションセキュリティテスト(DAST)実践
はじめに
こんにちは。
デプオプスリードカンパニーの蔡(サイ)です。
デプオプスリードカンパニーのLab活動は、毎週数名のメンバーが集まり、一定の時間を確保して新しいスキルを探索・学習する活動です。私が所属するチームは「DevSecOps Lab」です。「DevSecOps」をテーマとして、それに関する技術と実践の仕組みを探究するチームです。
本記事では、今期の研究テーマである「DAST」の代表的なOSSツール「OWASP ZAP」の入門とテスト環境の構築について紹介します。
「DAST」をテーマとして選んだ理由
現代のアプリケーション開発において、リリース速度の向上とセキュリティの確保を両立させることは極めて重要な課題となっているからです。リリース後にセキュリティ対策を講じるのでは遅く、コストがかかってしまう。なので開発の初期段階からセキュリティチェックを行う「シフトレフト」の考え方、ひいてはDevSecOpsの視点が不可欠となっています。
開発フェーズのセキュリティ対策には、ソースコードを解析する SAST (Static Application Security Testing) と、実行中のアプリに攻撃を仕掛ける DAST (Dynamic Application Security Testing) 、ライブラリや外部依存パッケージの脆弱性を検出するSCAなど手法があります。
様々な手法の中で、DAST の最大のメリットは「攻撃者と同じ視点で脆弱性を探せる」点にあります。DASTは、アプリケーションを実際に稼働させた状態で、外部から疑似的な攻撃を送ることで脆弱性を診断する手法です。ソースコードを解析するSASTとは異なり、実行環境を含めた「外側から見た安全性」を検証するのが最大の特徴です。
これは、システムが本番稼働する前に、「実際の攻撃に対する防御能力」を検証するものです。
OWASP ZAPって何?
DAST の実施方法を学ぶために、ツールとして OWASP ZAP を選択しました。
OWASP ZAP(以下、ZAP)は、OWASP (The Open Web Application Security Project) という世界的な非営利団体によって開発・提供されている、オープンソースの Web アプリケーション脆弱性診断ツールです。
ZAP はローカルプロキシとして動作し、ブラウザと Web サーバー間の通信を中継することで、アプリケーションの脆弱性を検出します。世界中のセキュリティ専門家や開発者に利用されており、入門ツールとして最適な選択肢の一つです。
DAST実施環境の構築
DAST のターゲットとして、脆弱性を含む Web アプリケーションを用意する必要があります。今回の対象は DVWA (Damn Vulnerable Web Application) というオープンソースの Web アプリケーションです。
DVWA は、意図的に脆弱性を組み込んだ PHP/MySQL 製の Webアプリケーションで、セキュリティ専門家や開発者がスキルを練習するためのプラットフォームとして広く利用されています。
DVWAへのDAST を実施するために、AWS 上に下記のような環境を構成しました。
テスト環境における構築のポイントを、下記にまとめました。
インフラの閉域構成
DVWAは意図的に多数の脆弱性を含んだウェブアプリケーションであるため、外部から攻撃される危険性があります。また、DASTを実施する際、大量のリクエストを送るため、自分の環境が破壊される可能性があり、無関係なサイトまでスキャン対象に含めてしまうと、攻撃行為とみなされる恐れがあります。
セキュリティの観点から、テスト環境は外部へのポートを完全に閉鎖した閉域構成を採用しました。OWASP ZAPとターゲットのウェブアプリケーション(DVWA)を構築した2つのEC2は、それぞれプライベートサブネット内に配置し、VPCピアリングを通じて通信を行います。
AWS Systems Manager Session Managerで接続
セキュリティ確保のためポートを開放しておらず、SSHによる直接接続はできません。ZAP ProxyとDVWAの操作画面は、「AWS Systems Manager Session Manager(以下、AWS SSM Session Managerと略称する)」のポートフォワーディング機能を使用し、ローカルマシンの特定のポートへのアクセスを、SSMを経由してリモートのサーバーへ転送します。これにより、ローカルのブラウザからZAPやDVWAの操作画面へアクセスすることが可能になります。
また、ZAP のプロキシポート(8090ポート)へのアクセスも、AWS SSM Session Managerのポートフォワーディングを経由して実現します。
プロキシ
プロキシはZAPの重要なメカニズムです。ZAPがスキャンを実行する際、プロキシサーバーとして機能し、ブラウザが送信するすべてのリクエスト(Request)と、サーバーから返されるすべてのレスポンス(Response)を監視する必要があります。これにより、HTTPヘッダーやCookieの情報を取得してWebサイト全体の構造を解析し、後続のアクティブスキャンの基盤を構築します。
今回のテスト環境は閉域構成を採用しており、外部からターゲットに直接アクセスすることができません。そのため、ブラウザから送信されるリクエストは、AWS SSM Session Managerのポートフォワーディング機能を使用し、ローカルの8090ポートをZAPのプロキシポートにマッピングします。これにより、ブラウザのリクエストをZAPプロキシを経由してターゲットに転送することが可能になります。プロキシの接続設定はFirefoxで行います。
スキャン先のウェブサイトのドメイン設定
本テスト環境でHTTPS接続をシミュレートするために、ブラウザからターゲットのウェブサイトにHTTPS接続でアクセスできるようにします。
その目的を実現するため、Dockerネットワーク内にNginxのコンテナをリバースプロキシとして追加し、自己署名SSL証明書をマウントします。例えば、ユーザーがブラウザで https://dast.target.test というURLにアクセスすると、リクエストはZAPのプロキシによってセキュリティ分析が行われます。続いてZAPはその後リクエストをNginxコンテナに転送し、NginxはSSLターミナルとしての処理とドメイン名の検証を行い、復号化されたトラフィックをターゲットウェブサイトに転送します。
このアーキテクチャにより、ZAPは暗号化通信でスキャンを実行でき、ターゲットウェブサイトのセキュリティ属性(Secure Cookieなど)の動作を正しく検証することが可能となります。
ZAPとNginxのコンテナ設定は、以下のYAMLファイルに記述しています。
version: '3.8'
services:
# SSL Terminal (Nginx)
zap-https-proxy:
image: nginx:alpine
container_name: zap-https-proxy
restart: unless-stopped
ports:
- "443:443"
networks:
zap-net:
aliases:
- dast.target.test
volumes:
- ./nginx.conf:/etc/nginx/conf.d/nginx.conf:ro
- ./ssl:/etc/nginx/ssl:ro
# OWASP ZAP (Webswing UI)
zap:
image: ghcr.io/zaproxy/zaproxy:stable
container_name: zap
restart: unless-stopped
user: zap
ports:
- "8080:8080"
- "8090:8090"
networks:
- zap-net
volumes:
- ${ZAP_DIR:-./zap_wrk}:/zap/wrk/:rw
command: zap-webswing.sh
networks:
zap-net:OWASP ZAP の使用方法
以下のセクションでは、OWASP ZAPの基本設定と使用手順について簡単に紹介します。
OWASP ZAP証明書のインポート
ZAPの本質は、「割り込み型プロキシ(Interception Proxy)」です。その仕組みは、ブラウザ(クライアント)とサーバーの間に自らを配置することにあります。これにより、以下のような機能を実現しています:
トラフィックの可視化(Visibility): ZAPはブラウザが送信したHTTPヘッダー、隠しパラメーター、Cookie、およびサーバーのレスポンス内容を確認できます。
傍受とデータの改ざん(Interception & Manipulation): ZAPはリクエストを送信する前にパラメーターを手動で修正してから送信することができて、サーバーのロジック脆弱性をテストできます。
サイトマップの構築(Site Map): プロキシを通じて、ZAPは閲覧したすべてのページを記録し、対象Webサイトの構造を自動的にマッピングします。これは後続のアクティブスキャン(Active Scan)のフェーズにおいて非常に重要です。
Webサイトにアクセスする際、ZAPはサーバーの証明書を傍受し、「自身のルートCA証明書」を使ってブラウザ向けの偽証明書を動的に生成します。ブラウザがZAPのCAを信頼していない場合、ブラウザはこれを不正と判断して接続をブロックし、ZAPはトラフィックを解析できません。そのため、ZAPが生成したCA証明書をローカルのブラウザにインポートする必要があります。
ZAPの証明書を取得・保存する手順は以下の通りです:
(1)「Options」→「Network」→「Local Servers/Proxies」→「Port」に8090を入力します。
※「Port」は、ZAPで監視するプロキシの転送ポートです。一般的に8090ポートを使用します。
(2)「Options」→「Network」→「Server Certificates」の項目をクリックして、証明書を保存します。
(3)証明書をブラウザにインポートします。
証明書をブラウザにインポートする際、ブラウザによって設定方法が異なります。本文ではFirefoxを使用して操作を行います:
Firefox→「設定」→「プライバシーとセキュリティー」→「証明書」→「証明書を表示」
前に保存したZAPの証明書を読み込んで、「ウェブサイトの識別を信頼する」の項目にチェックを入れて保存します。
プロキシサーバーの設定
異なるブラウザでプロキシサーバーを設定する方法はいくつかあります。本文では上記の例に続き、Firefoxを使用してプロキシサーバーを設定します。
Firefoxでプロキシを設定するオプションは以下の通りです:
Firefox→「設定」→「一般」→「ネットワーク設定」→「接続設定」
「インターネット接続設定」のページで下記のように設定します。
ZAPにおけるContextsの設定方法
OWASP ZAPにおけるコンテキストとは、テスト対象となる特定のWebアプリケーションに関連する一連のURLを関連付け、グループ化するための仕組みです。
コンテキスト(Contexts)を作成することで、テスト対象のWebアプリケーションを他の無関係なドメインから切り離して整理することができ、スコープ(テスト範囲)を明確に設定するための基礎となります。各テスト対象のWebアプリケーションに対して、それぞれ新しいコンテキストを定義することができます。コンテキスト内ではスコープの設定に加えて、正規表現、認証、フィルターなどの設定も管理することができます。
コンテキストの設定方法は以下です。
ZAPで検出されたURLリストの中から、スキャンしたい対象URLを右クリックし、「Include in Context」を選択します。「Default Context」を使用しない場合は、今回の対象ウェブサイトのURLを選択してください。
「Session Properties」の設定画面が開いたら、対象ウェブサイトのタイトルをクリックし、「Context Name」欄にコンテキスト名を入力します。今回はContext 名を「DVWA」にします。
設定したコンテキスト名が「Contexts」のツリーに表示されます。対象ウェブサイトのフォルダーにもターゲットアイコンが表示されます。これでコンテキストの追加が完了しました。
アプリケーションの認証設定
Webセキュリティスキャンを行う際、「自動ログイン(Automated Authentication)」はスキャンの結果を決定する重要な要素です。Webアプリケーション(DVWAなど)の機能やロジックの大部分(例えば個人情報の設定、データ管理、APIなど)はログインしてから操作できます。自動ログインを設定していない場合、ZAPはログインページ、登録ページ、パスワードリセットページしかアクセスできません。
自動ログイン情報を設定した後、ZAPは「ログイン後の状態」に入り、保護されたURLをクロールできます。なぜなら、ZAPがログイン済みの状態でなければ、「認証」に関連する機能をトリガーできず、高リスクな脆弱性を発見することができないからです。
本文のテスト対象である「DVWA」はフォームベースの認証方式を使用するWebアプリです。そのため、本文ではフォームベースの認証方式のみを紹介します。
自動ログインの設定手順は以下の通りです。
まずDVWAのログインページからログインします。
「History」セクションの「SetCookie」のページを見つけてください。通常は「login」というページです。
そのページの行を右クリックし、メニューから「Show in Sites Tab」を選択すると、「Sites」タブの該当項目に移動します。
「Request」タブを選択すると、先ほどログインした際にブラウザからWebサーバーへ送信したヘッダーとボディがZAPの画面に表示されています。そのリクエストのフォーマットを記録してください。
コンテキストの「Authentication」設定画面を開き、「Login Request POST Data」欄に、先ほど記録したフォーマットに従ってパラメータ名を設定してください。
ZAPは 「Regex Pattern used to identify Logged In messages」に入力した文字列を基に、現在の認証状態を判断します。そのため、ログイン後にのみ表示されるHTMLの要素を使用することが推奨されます。一般的には、ログイン成功後に「index」ページの内容を使用します。
同様に、「Regex Pattern used to identify Logged Out messages」には、未ログイン状態の画面の要素を使用します。一般的には、「login」ページの要素を使用します。
利用する要素は「Response」タブのボディセクションで取得できます。
コンテキストの自動認証の設定が完了すると、「login」ページに以下のような扉のアイコンが表示されます。
「自動認証」にはユーザーの情報の登録も必要です。 ユーザーの情報の追加方法は、「Session Properties」の設定画面で、「DVWA(先ほど登録したコンテキスト)」→ 「Add」でユーザー名とパスワードを追加します。
「自動認証」を有効にするには、「Forced User Mode Enabled」ボタンをクリックします。
「Spider」と「Passive Scan」
「Spider」の主な役割はWebサイト全体をクロール(Crawl)することです。指定したURLを起点に、ページ内のすべてのハイパーリンク(<a>タグ)、フォーム(<form>タグ)、および静的リソースを自動的に探索します。ZAPはこれらのページを「認識」した上で、脆弱性テストを実行します。
「Spider」を実行する前に、「Forced User Mode Enabled」ボタンをクリックして「Forced User Mode」を起動します。
ターゲットのURLを右クリックし、「Attack」→「Spider」の順に選択して「Spider」を実行します。「Spider」の設定画面が起動して、どのユーザーの認証情報を 使用するかを確認するダイアログが表示されます。先ほど登録したユーザー情報を選択してください。
実行の結果、「Spider」が探索したURLが画面に並んでいます。十分なURLが探索されていない場合は、自動認証の設定を見直した上で、「Spider」を再度実行してください。
「Passive Scan」(受動的スキャン)は攻撃文字列(ペイロード)を一切送信しません。ZAPプロキシを起動するだけで、パッシブスキャンはバックグラウンドで自動的に動作します。データを改ざんせず、追加のリクエストも送信しないため、対象サーバーのパフォーマンスやデータ状態に一切影響を与えません。そのため、パッシブスキャンの実行に追加の設定は必要ありません。
「Active Scan」を実施
OWASP ZAPの「Active Scan(能動的スキャン)」は、アプリケーションに対して実際に攻撃リクエストを送信し、様々な脆弱性をテストする機能です。これも本文で紹介したい主要な機能です。
Active Scanはサーバーに対して様々な悪意のあるペイロード(Payloads)を能動的に送信します。 例えば:
ロールベースアクセス制御:各URLのパラメーター、ヘッダー、Cookieに対してブルートフォーステストを行い、サーバーにエラーや異常な動作を引き起こすことを試みます。
脆弱性の検証:例えば、' OR 1=1 ' を挿入してSQLインジェクションをテストしたり、<script>alert(1)</script>を挿入してXSSをテストしたりします。これらの高リスクな脆弱性が実際に存在するかどうかは、能動的なリクエストの送受信によってのみ確認できます。
Active Scan は、ZAPが高価値なレポートを生成するための鍵です。それがなければ、レポートには「セキュリティヘッダーの欠落」のような軽微な問題しか現れません。それがあってこそ、データベースの漏洩やシステムの乗っ取りにつながりかねない高リスクの脆弱性を掘り起こすことができるのです。
Active Scanは無許可のシステムへの実行は不正アクセスとなります。そのため、必ずスコープの範囲を適切に設定してから実行してください。
「Active Scan」を実施する際は、「Spider」と同様に、ターゲットのURLを右クリックし、メニューから「Active Scan」を選択することで実行を開始します。
「Active Scan」の実行画面は下記のようになります。
進捗バー左側のパソコンアイコンをクリックすることで、スキャンの詳細画面が表示されます。実行中のDASTの項目と進捗状態は画面中で確認できます。
上の画像は「Spider」実行後の、下の画像は「Active Scan」実行後のアラート数を示しています。「Active Scan」を実施した結果、新たな脆弱性が検出されたことが確認できます。
レポートを生成する
DAST実行の完了した後、レポートを生成することができます。
レポート生成の画面は「Report」→ 「Generate Report」で開きます。
レポート出力には複数の形式を選択可能ですが、本手順では「Traditional PDF Report」の利用を推奨します。生成後、PDFのレポートをローカルにダウンロードできます。
「Scope」タブで、生成したいコンテキストを選択します。「Generate Report」をクリックすると、レポートのダウンロードが開始されます。
まとめ
一般的な開発プロセスにおいて、SAST(静的解析)やSCA(依存関係チェック)はすでにCI/CDフローに組み込まれつつあります 。一方で、DAST(動的解析)は専門的なツールや知見が必要だというイメージから、後回しにされがちな領域でした。
今回OWASP ZAPという強力なOSSを通じてDASTを実践し、以下の重要な知見が得られました:
「外側」からの安全性検証:ソースコードだけでなく、ネットワーク構成や認証ロジックを含めた、実際の稼働環境における安全性を確認できる。
攻撃者視点の獲得:ハッカーがどの経路から侵入し、実行時にどのような挙動を示すのかを明確にイメージできるようになる 。
DevSecOpsの加速:リリース前に脆弱性を掘り起こすことで、手戻りを最小限に抑えつつ、安全なプロダクトを迅速に届ける基盤となる。
OWASP ZAPには、今回紹介したGUI操作以外にも、APIを利用した自動化などの強力な機能が備わっています。次回の投稿では、これらをCI/CDパイプラインへ統合し、安全性を継続的に担保する仕組みについて紹介する予定です。
What is BEMA!?
Be Engineer, More Agile


