DASTブラウザベースアナライザのトラブルシューティング

以下のトラブルシューティングシナリオは、お客様のサポート事例から収集したものです。ここに記載されていない問題が発生した場合、またはここに記載されている情報では問題が解決しない場合は、サポートチケットを作成してください。詳細はGitLabサポートページをご覧ください。

何か問題が発生した場合

DASTスキャンで何か問題が発生した場合、特定のエラーメッセージが表示されたら、既知の問題を確認してください。

そうでない場合は、以下の質問に答えることで問題を発見してください:

期待される結果は何ですか?

DASTスキャンでイシューに遭遇したユーザーの多くは、スキャナが何をすべきかを大まかに理解しています。例えば、特定のページがスキャンされない、ページ上のボタンが選択されないなどです。

可能な限り、問題を切り分けて、解決策を絞り込むようにしてください。例えば、DASTが特定のページをスキャンしていない状況を考えてみましょう。DASTはどこからそのページを見つけたのでしょうか?どのような経路でそのページに移動したのでしょうか?参照先のページに、DASTが選択すべきなのに選択しなかった要素がありましたか?

その結果は人間が達成できるものですか?

人間が手動でアプリケーションを走査できない場合、DASTはアプリケーションを走査できません。

予想される結果がわかっている場合、マシンのブラウザを使って手動で再現してみてください。例えば

  • 新しいシークレット/非公開ブラウザウィンドウを開きます。
  • 開発者ツールを開きます。コンソールにエラーメッセージが表示されないか確認してください。
    • Chromeの場合:View -> Developer -> Developer Tools.
    • Firefoxの場合:Tools -> Browser Tools -> Web Developer Tools.
  • 認証する場合
    • DAST_AUTH_URL にアクセスしてください。
    • DAST_USERNAME_FIELDDAST_USERNAME と入力。
    • DAST_PASSWORD_FIELDDAST_PASSWORD と入力。
    • DAST_SUBMIT_FIELD を選択してください。
  • リンクを選択し、フォームに入力します。正しくスキャンされていないページに移動します。
  • アプリケーションの動作を観察してください。自動スキャナにとって問題になりそうなことがないか注意してください。

DAST が動作しない理由は?

以下の場合、DASTは正しくスキャンできません:

  • CAPTCHA があります。スキャンするアプリケーションのテスト環境では、これらをオフにしてください。
  • 対象のアプリケーションにアクセスできません。GitLab RunnerがDAST設定で使用したURLを使ってアプリケーションにアクセスできることを確認してください。

アプリケーションはどのように動作しますか?

アプリケーションの動作を理解することは、DASTスキャンが機能しない原因を突き止めるために不可欠です。例えば、以下のような状況では、追加の設定が必要になる場合があります。

  • 要素を隠すポップアップ モーダルがありますか?
  • 読み込んだページが一定時間後に劇的に変化することはありますか?
  • アプリケーションのロードが特に遅いか速いか?
  • ターゲットアプリケーションのロード中にぎくしゃくしていますか?
  • クライアントの場所によってアプリケーションの動作が異なりますか?
  • アプリケーションは単一ページですか?
  • アプリケーションはHTMLフォームを送信しますか、それともJavaScriptとAJAXを使いますか?
  • アプリケーションはウェブソケットを使いますか?
  • アプリケーションは特定のWebフレームワークを使っていますか?
  • ボタンを選択すると、フォームの送信を続行する前に JavaScript が実行されますか?それは速いですか、遅いですか?
  • 要素やページの準備ができる前に、DASTが要素を選択したり検索したりしている可能性はありませんか?

DASTは何をしているのですか?

DASTが何をしているかを理解するには、ログを取るのが一番です:

ブラウザベースのアナライザーロギング

アナライザーのログは、スキャンの問題を診断するのに役立つ最も便利なツールの1つです。アナライザーのさまざまな部分をさまざまなレベルでログに記録できます。

ログ・メッセージの形式

ログメッセージの形式は[time] [log level] [log module] [message] [additional properties]

例えば、以下のログエントリはレベルINFOCRAWL ログモジュールの一部であり、メッセージCrawled path 、追加プロパティnav_idpathを持ちます。

2021-04-21T00:34:04.000 INF CRAWL Crawled path nav_id=0cc7fd path="LoadURL [https://my.site.com:8090]"

ログ宛先

ログはファイルかコンソール(CI/CDジョブのログ)に送られます。コンソールログにはDAST_BROWSER_LOG という環境変数を、ファイルログにはDAST_BROWSER_FILE_LOG という環境変数を使うことで、それぞれのログ送信先を設定できます。

使用例:

include:
  - template: DAST.gitlab-ci.yml

dast:
  variables:
    DAST_BROWSER_SCAN: "true"
    DAST_BROWSER_LOG: "auth:debug"                               # console log defaults to INFO level, logs AUTH module at DEBUG
    DAST_BROWSER_FILE_LOG: "loglevel:debug,cache:warn"           # file log defaults to DEBUG level, logs CACHE module at WARN
    DAST_BROWSER_FILE_LOG_PATH: "$CI_PROJECT_DIR/dast-scan.log"  # Save the file log in the project directory so it can be recognized as an artifact
  artifacts:
    paths:
      - dast-scan.log
    when: always

ログレベル

設定可能なログレベルは以下のとおりです:

ログモジュールコンポーネント概要詳細
TRACE機能の特定の、しばしばノイズの多い内部動作に使用されます。 
DEBUGフィーチャーの内部構造を記述します。診断目的で使用します。 
INFOスキャンの高レベルの流れと結果を記述します。指定がない場合の既定のレベル。
WARNDAST が回復してスキャンを続行するエラー状況を記述します。 
FATAL/ERROR/PANIC 終了前の回復不可能なエラーについて説明します。 

ログモジュール

LOGLEVEL は、ログ送信先のデフォルトのログレベルを設定します。以下のモジュールのいずれかが設定されている場合、DAST はデフォルトのログレベルよりもそのモジュールのログレベルを優先して使用します。

ログの設定が可能なモジュールは以下のとおりです:

ログモジュールコンポーネント概要
ACTIVアクティブアタックに使用。
AUTH認証スキャンの作成に使用します。
BPOOLクローリングのために貸し出されるブラウザのセット。
BROWSブラウザの状態やページのクエリに使用します。
CACHEキャッシュされた HTTP リソースのキャッシュヒット・ミスに関するレポーターに使用します。
CHROMChrome DevToolsメッセージのログに使用します。
CONTADevToolsメッセージからHTTPリクエストとレスポンスの一部を収集するコンテナに使用されます。
CRAWLCoreクローラーアルゴリズムに使用されます。
DATAB内部データベースへのデータの永続化に使用されます。
LEASEブラウザを作成し、ブラウザプールに追加します。
MAINクローラーのメインイベントループのフローに使用されます。
NAVDBナビゲーションエントリーを保存するための永続化メカニズムに使用されます。
REGEX正規表現を実行する際のパフォーマンス統計の記録に使用します。
REPTレポートの生成に使用します。
STATスキャン実行中の一般的な統計に使用されます。
VLDFN脆弱性定義の読み込みと解析に使用されます。
WEBGWアクティブチェックの実行時にターゲットアプリケーションに送信されるメッセージのログを記録するために使用します。

例 - クロールされたパスのログ

ログのモジュールCRAWLDEBUG に設定し、スキャンのクロールフェーズで見つかったナビゲーションパスをログに記録します。これはDASTがターゲットアプリケーションを正しくクロールしているかどうかを把握するのに役立ちます。

include:
  - template: DAST.gitlab-ci.yml

dast:
  variables:
    DAST_BROWSER_LOG: "crawl:debug"

例えば、以下の出力は、https://example.com にあるページのクロール中に発見した4つのアンカーリンクを示しています。

2022-11-17T11:18:05.578 DBG CRAWL executing step nav_id=6ec647d8255c729160dd31cb124e6f89 path="LoadURL [https://example.com]" step=1
...
2022-11-17T11:18:11.900 DBG CRAWL found new navigations browser_id=2243909820020928961 nav_count=4 nav_id=6ec647d8255c729160dd31cb124e6f89 of=1 step=1
2022-11-17T11:18:11.901 DBG CRAWL adding navigation action="LeftClick [a href=/page1.html]" nav=bd458cc1fc2d7c6fb984464b6d968866 parent_nav=6ec647d8255c729160dd31cb124e6f89
2022-11-17T11:18:11.901 DBG CRAWL adding navigation action="LeftClick [a href=/page2.html]" nav=6dcb25f9f9ece3ee0071ac2e3166d8e6 parent_nav=6ec647d8255c729160dd31cb124e6f89
2022-11-17T11:18:11.901 DBG CRAWL adding navigation action="LeftClick [a href=/page3.html]" nav=89efbb0c6154d6c6d85a63b61a7cdc6f parent_nav=6ec647d8255c729160dd31cb124e6f89
2022-11-17T11:18:11.901 DBG CRAWL adding navigation action="LeftClick [a href=/page4.html]" nav=f29b4f4e0bdee70f5255de7fc080f04d parent_nav=6ec647d8255c729160dd31cb124e6f89

Chromium DevToolsのロギング

caution
DevTools メッセージのログはセキュリティ上のリスクがあります。出力にはユーザー名、パスワード、認証トークンなどのシークレットが含まれます。出力は GitLab サーバーにアップロードされ、ジョブログに表示される可能性があります。

DAST ブラウザベースのスキャナは、Chrome DevTools プロトコルを使用して Chromium ブラウザをオーケストレーションします。DevToolsメッセージのログは、ブラウザが何をしているのかの透明性を提供するのに役立ちます。例えば、ボタンを選択しても動作しない場合、DevToolsメッセージはブラウザのコンソールログにその原因がCORSエラーであることを示すかもしれません。DevTools メッセージを含むログのサイズは非常に大きくなる可能性があります。このため、短い期間のジョブでのみ有効にする必要があります。

すべてのDevToolsメッセージをログに記録するには、CHROM ログモジュールをtrace にし、ロギングレベルを設定します。以下はDevToolsログの例です:

2022-12-05T06:27:24.280 TRC CHROM event received    {"method":"Fetch.requestPaused","params":{"requestId":"interception-job-3.0","request":{"url":"http://auth-auto:8090/font-awesome.min.css","method":"GET","headers":{"Accept":"text/css,*/*;q=0.1","Referer":"http://auth-auto:8090/login.html","User-Agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/105.0.5195.102 Safari/537.36"},"initialPriority":"VeryHigh","referrerPolicy":"strict-origin-when-cross-origin"},"frameId":"A706468B01C2FFAA2EB6ED365FF95889","resourceType":"Stylesheet","networkId":"39.3"}} method=Fetch.requestPaused
2022-12-05T06:27:24.280 TRC CHROM request sent      {"id":47,"method":"Fetch.continueRequest","params":{"requestId":"interception-job-3.0","headers":[{"name":"Accept","value":"text/css,*/*;q=0.1"},{"name":"Referer","value":"http://auth-auto:8090/login.html"},{"name":"User-Agent","value":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/105.0.5195.102 Safari/537.36"}]}} id=47 method=Fetch.continueRequest
2022-12-05T06:27:24.281 TRC CHROM response received {"id":47,"result":{}} id=47 method=Fetch.continueRequest

DevTools ログ・レベルのカスタマイズ

Chrome DevToolsのリクエスト、レスポンス、イベントはドメインごとに名前空間化されています。DASTでは、各ドメインおよびメッセージを含む各ドメインで異なるログ設定を行うことができます。環境変数DAST_BROWSER_DEVTOOLS_LOG は、セミコロンで区切られたロギング設定のリストを受け入れます。ロギング設定は[domain/message]:[what-to-log][,truncate:[max-message-size]] という構造体を用いて宣言されます。

  • domain/message はロギングされる内容を参照します。
    • Default はすべてのドメインとメッセージを表す値として使用できます。
    • 例えば、Browser,CSS,Page,Network のようにドメインを指定することができます。
    • 例えば、Network.responseReceived のように、メッセージ付きのドメインを指定することができます。
    • 複数の設定が適用される場合、最も具体的な設定が使用されます。
  • what-to-log ログを記録するかどうか、何を記録するかを指定します。
    • message はメッセージを受信したことをログに記録し、メッセージの内容は記録しません。
    • messageAndBody メッセージの内容とともにメッセージをログに記録します。truncate と併用することをお勧めします。
    • suppress メッセージをログに残しません。ノイズの多いドメインやメッセージを消音するために使用します。
  • truncate は印刷されるメッセージのサイズを制限するオプション設定です。

例 - 全てのDevToolsメッセージを記録

どこから始めればいいのかわからないときに、すべてのログを記録するために使用します。

include:
  - template: DAST.gitlab-ci.yml

dast:
  variables:
    DAST_BROWSER_FILE_LOG: "chrom:trace"
    DAST_BROWSER_FILE_LOG_PATH: "/zap/wrk/dast-scan.log"
    DAST_BROWSER_DEVTOOLS_LOG: "Default:messageAndBody,truncate:2000"
  artifacts:
    paths:
      - dast-scan.log
    when: always

例 - HTTP メッセージのログ

リソースが正しく読み込まれないときに有用です。HTTP メッセージのイベントは、リクエストを継続するか失敗するかの決定と同様にログに記録されます。ブラウザコンソールでのエラーもログに記録されます。

include:
  - template: DAST.gitlab-ci.yml

dast:
  variables:
    DAST_BROWSER_FILE_LOG: "chrom:trace"
    DAST_BROWSER_FILE_LOG_PATH: "/zap/wrk/dast-scan.log"
    DAST_BROWSER_DEVTOOLS_LOG: "Default:suppress;Fetch:messageAndBody,truncate:2000;Network:messageAndBody,truncate:2000;Log:messageAndBody,truncate:2000;Console:messageAndBody,truncate:2000"
  artifacts:
    paths:
      - dast-scan.log
    when: always

Chromium のログ

まれにChromiumがクラッシュするイベントが発生した場合、ChromiumのプロセスSTDOUTSTDERR をログに書き出すと便利です。環境変数DAST_BROWSER_LOG_CHROMIUM_OUTPUTtrue に設定することで、この目的が達成されます。

DAST は多くの Chromium プロセスを起動および停止します。DAST は各プロセスの出力を、ログモジュールLEASE およびログレベルINFO を持つすべてのログ宛先に送信します。

使用例:

include:
  - template: DAST.gitlab-ci.yml

dast:
  variables:
    DAST_BROWSER_LOG_CHROMIUM_OUTPUT: "true"

既知の問題

ログのコンテナresponse body exceeds allowed size

デフォルトでは、DASTはHTTPレスポンスボディが10MB以下のHTTPリクエストを処理します。そうでない場合、DASTはスキャンが失敗する原因となる応答をブロックします。この制限は、スキャン中のメモリ消費を減らすことを目的としています。

ログの例を以下に示します。https://example.com/large.js で見つかった JavaScript ファイルのサイズが制限を超えているため、DAST はブロックしました:

2022-12-05T06:28:43.093 WRN BROWS response body exceeds allowed size allowed_size_bytes=1000000 browser_id=752944257619431212 nav_id=ae23afe2acbce2c537657a9112926f1a of=1 request_id=interception-job-2.0 response_size_bytes=9333408 step=1 url=https://example.com/large.js
2022-12-05T06:28:58.104 WRN CONTA request failed, attempting to continue scan error=net::ERR_BLOCKED_BY_RESPONSE index=0 requestID=38.2 url=https://example.com/large.js

これは設定DAST_MAX_RESPONSE_SIZE_MB を使って変更することができます。例えば

include:
  - template: DAST.gitlab-ci.yml

dast:
  variables:
    DAST_MAX_RESPONSE_SIZE_MB: "25"