メインコンテンツまでスキップ

自動巡回

info

本チュートリアルで扱う機能は、Web アプリケーション診断機能をご契約いただいた組織でのみご利用いただけます。

Shisho Cloud では診断対象アプリケーションのエンドポイントを洗い出すために、自動巡回機能を提供しています。アプリケーションのトップページを入力すると、Shisho Cloud はページ中のリンクやフォームを辿ってアプリケーションを自動で巡回し、エンドポイントを洗い出します。

セットアップ

ログインが必要なアプリケーションなど、アプリケーションにアクセスするために特定の操作や設定が必要な場合は、巡回の前に設定が必要です。一方で特段の準備なくアクセスできるアプリケーションを診断する場合は、そのまま「巡回」の節に進んでください。

ログインが必要なアプリケーション

ユーザー名とパスワードをフォーム POST /login に送信すると Cookie がセットされるようなアプリケーションを例に、設定の手順を説明します。

設定の手順は大きく3つのステップから構成されます:

  1. ログイン用のエンドポイントを Shisho Cloud に登録するために、ログインフォームに対する巡回を実行する
  2. ログインの手順を表す「シナリオ」を定義する
  3. ログインのレスポンスから Cookie を抽出し、それを巡回・診断時のリクエストに付与するための「認証設定」を追加する

ログインフォームの巡回

まず、ログインフォームをエンドポイントとして登録するため、ログインフォームに対して巡回を実行しましょう。 「巡回ジョブ」タブ (https://cloud.shisho.dev/[orgid]/applications/[appid]/jobs/find) に移動し、「自動巡回を実行」ボタンをクリックします。

「巡回ジョブ」タブ

巡回ジョブのエントリーポイントとして、ログインフォームの URL を入力します。また巡回を早く終わらせるため、巡回の深さは 1 に設定します。以上を入力したら、「予約」ボタンをクリックします。

巡回ジョブ予約画面

巡回ジョブを予約してからしばらく待つと、Shisho Cloud は指定した URL を起点に自動でフォーム等を探索し、エンドポイントとして登録します。ジョブの状態が「Completed」になったら、「エンドポイント」タブを開き、ログインフォームがエンドポイントとして登録されたことを確認します。

エンドポイント一覧タブ

シナリオの定義

次に、ログイン手順を表す「シナリオ」を登録します。アプリケーションの「シナリオ」タブ (https://cloud.shisho.dev/[orgid]/applications/[appid]/scenarios) に移動し、「シナリオを追加」ボタンをクリックします。

シナリオ一覧タブ

シナリオ追加画面では、ログインするために送るべきリクエストの列を指定します。このチュートリアルでは、ログインフォーム送信リクエスト (POST /login) において、ユーザー名とパスワードに加えて、GET /login のレスポンスで付与される Cookie と CSRF トークンを送信する必要がある場合の設定方法を説明します。シナリオの定義に関する網羅的な説明については、リファレンスを参照してください。

シナリオ追加画面

それぞれの入力項目について説明していきます。

画面最上部の「名前」欄は任意入力ですが、わかりやすいように「ログイン」などと入力しておきましょう。

アプリケーションにログインするためには GET /loginPOST /login の2つのリクエストを送信する必要があるので、「Add step」ボタンをクリックしてステップを2つ用意します。それぞれのステップの Endpoint 欄にある「Select」ボタンをクリックし、Step 1. では GET /login、Step 2. では POST /login を選択します。選択肢のエンドポイントが多すぎる場合には、検索欄にパスを入力して絞り込むと探しやすいでしょう。

パスを入力してエンドポイントを絞り込む

Step 1. と Step 2. それぞれのエンドポイントを選択したら、「Select」ボタンをクリックして選択を確定します。

最後に、Step 1. のリクエストで Cookie と CSRF トークンを抽出し、その結果を Step 2. のリクエストに注入するための設定を入力します。なお、このチュートリアルで題材とするアプリケーションでは、POST /login のリクエストを送信する際に必要な Cookie と CSRF トークンが、それぞれ以下のようにして GET /login のレスポンスに記載されていると仮定します。

  • Cookie: レスポンスヘッダー中の Set-Cookie: session=XXXX expires=...
  • CSRF トークン: レスポンスボディ中の <input type="hidden" name="csrf_token" value="XXXX">

これを踏まえて、Step 1. の YAML 入力欄には、以下のような設定を入力します。

extractors:
# Set-Cookie ヘッダーを抽出
- name: cookie
type: regex
regex:
- "Set-Cookie: (session=[a-zA-Z0-9]+)"
group: 1
part: header

# CSRF トークンを抽出
- name: csrf_token
type: xpath
xpath:
- '//form[@action="/login"][@method="post"]//input[@name="csrf_token"]'
attribute: value

1つ目の項目により、GET /login のレスポンスヘッダーに対して Set-Cookie: (session=[a-zA-Z0-9]+) という正規表現でマッチが行われ、group: 1 という設定により1つ目のグループである session=XXXX の部分が抽出され、name: cookie という設定により cookie という名前の変数に値が格納されます。 また2つ目の項目により、指定した XPath に基づいて、<form action="/login" method="post"> のような要素の内部にある <input name="csrf_token" value="..."> のような要素が検索され、その value 属性の値が csrf_token という名前の変数に格納されます。 なおレスポンスに Cookie や CSRF トークンが異なる形で記載されているアプリケーションでは、リファレンスを参考に、適切な正規表現や XPath を入力してください。

これで Step 1. の入力は以上です。Step 2. では抽出した変数を POST /login のリクエストに注入するために、YAML 入力欄に以下のような設定を入力します。

bindings:
# Cookie を注入
- type: header
key: Cookie
extractorName: cookie

# CSRF トークンを注入
- type: body
key: .csrf_token
extractorName: csrf_token

1つ目の項目により、先ほど抽出した cookie 変数の値が、Cookie ヘッダーに設定されます。また2つ目の項目により、csrf_token 変数の値が、POST パラメータ .csrf_token に設定されます。CSRF トークンのパラメータ名が異なるアプリケーションでは、リファレンスを参考に、key の部分を当該パラメータ名に置き換えてください。

以上の設定を入力したら、「保存」ドロップダウンをクリックし、「保存」を選択してください。

認証設定の追加

最後に、認証設定を追加します。アプリケーションの「認証設定」タブ (https://cloud.shisho.dev/[orgid]/applications/[appid]/preconditions) に移動し、「追加」ボタンをクリックします。

認証設定タブ

認証設定の追加画面では、「ログインリクエストを送信してレスポンスから Set-Cookie ヘッダーを抽出し、その Cookie の値を巡回や診断中のリクエストに付与する」ための設定を行います。なお認証設定に関する網羅的な説明については、リファレンスを参照してください。

認証設定追加画面

それぞれの入力項目について説明していきます。

まず、巡回や診断中のリクエストに対して Cookie ヘッダーを付与したいですから、「認証情報の付加箇所」は「ヘッダー」を選択し、「ヘッダー名」欄には「Cookie」と入力します。付与する Cookie の値はログイン操作のレスポンスから抽出したいですから、「認証リクエストを送信して抽出」を選択します。

「認証リクエストのシナリオ」には、先ほど作成したシナリオを指定します。右側の「Select」ボタンをクリックして当該シナリオを選択してください。前述の手順に従っていれば、シナリオは「ログイン」という名前で登録されているでしょう。シナリオの個数が多く見つからない場合は、「エンドポイントからシナリオを絞り込む」の欄にてログイン用エンドポイントのパスを入力し当該エンドポイントを選択すると、そのエンドポイントを用いるシナリオだけに絞り込まれ、探しやすくなります。

エンドポイントからシナリオを絞り込む

シナリオを選択したら、「Select」ボタンをクリックして選択を確定します。

「認証リクエストのパラメータ」には、ログインシナリオに注入するパラメータ (ユーザー名やパスワードなど) を設定します。例えばユーザー名が test、パスワードが n}0b6P@5jkjy&7<KFdwANh9f>IY_?,Ty である場合には、以下のように入力します。先ほど作成したログイン用シナリオは、GET /login を送信した後に POST /login を送信するものでしたので、POST /login にパラメータを注入するためには、stepIndex1 に設定します (stepIndex は 0-indexed で指定することに注意してください)。なお、パラメータ名が異なるアプリケーションでは、リファレンスを参考に、key の部分を適切なパラメータ名に置き換えてください。

- type: body
key: .username
value: test
stepIndex: 1 # 0-indexed
- type: body
key: .password
value: n}0b6P@5jkjy&7<KFdwANh9f>IY_?,Ty
stepIndex: 1 # 0-indexed

「認証情報の抽出方法」には、ログイン操作のレスポンスから Cookie を抽出するための設定を入力します。レスポンスにおける Set-Cookie: session=XXXX expires=... の中の session=XXXX という部分を抽出するために、以下のように抽出方法を指定します。他の抽出方法については、リファレンスを参照してください。

type: regex
part: header
group: 1
regex:
- "Set-Cookie: (session=[a-zA-Z0-9]+)"

「認証情報の更新条件」の欄では、Cookie の更新が必要となる条件を設定します。例えば Cookie の有効期限が1時間である場合には、余裕を持たせて55分経過後に Cookie を更新するよう、以下のように入力すると良いでしょう。この設定項目に関する網羅的な説明については、リファレンスを参照してください。

- type: BLANK # 初期状態で更新
config: {}
- type: EXPIRE # 生成から55分以上経過していたら更新
config:
expiresIn: 55m

以上の項目を入力したら、「保存」ボタンをクリックします。

巡回

「巡回ジョブ」タブ (https://cloud.shisho.dev/[orgid]/applications/[appid]/jobs/find) に移動し、「巡回ジョブを実行」ボタンをクリックします。

「巡回ジョブ」タブ

巡回ジョブの「エントリーポイント」欄には、巡回の起点となる URL を指定します。ログインが不要なアプリケーションではトップページを、ログインが必要なアプリケーションではログイン後のトップページを指定すると良いでしょう。エントリーポイントを入力したら、「予約」ボタンをクリックします。

巡回ジョブを予約してからしばらく待つと、Shisho Cloud は指定した URL を起点にページ内のリンクやフォーム等を自動で探索して辿り、エンドポイントやシナリオを登録していきます。

巡回ジョブ詳細画面

巡回結果の修正

Shisho Cloud は巡回中にフォームを検出した際に、入力欄を自動で記入して送信します。しかし場合によっては、自動で入力されたパラメータが適当でなく、フォームの正常送信後の画面に遷移できないことがあります。そのような場合には、入力すべきパラメータを手動で指定し、フォームの正常送信後の画面から巡回を再開させることができます。

「エンドポイント」タブを開き、パラメータを修正したいエンドポイントを選択します。

エンドポイントタブ

エンドポイントの更新画面では、YAML 入力欄にエンドポイントのパラメータが記載されています。例えば以下のエンドポイントには、name というパラメータに対し、shisho という値が自動で入力されています。

エンドポイント更新画面

name パラメータの値として shisho ではなく例えば テスト という値を指定したい場合には、value の箇所を テスト に書き換えます。

エンドポイント更新画面

パラメータを修正したら、右上の「保存」ドロップダウンをクリックし、「保存して巡回を再開」をクリックしてください。すると、この修正したパラメータを用いてリクエストが送信され、そこから巡回が再開されます。

シナリオの修正

エンドポイントの機能によっては、そのエンドポイントにリクエストを送信する前に、別のリクエストを送信しておく必要があることがあります。例えば削除系のエンドポイントでは、削除のリクエストを送信する前に、削除対象のリソースを作成しておく必要があるでしょう。このようなケースでは、「作成リクエストを送信した後に削除リクエストを送信する」というシナリオを設定することにより、削除系のエンドポイントを効果的に診断できます。

シナリオを編集するには、「シナリオ」タブを開き、編集したいシナリオを選択します。

シナリオタブ

「更新」タブを選択すると、シナリオを編集できます。

シナリオ更新画面

このチュートリアルでは、削除リクエストの前に作成リクエストを送信しておくようなシナリオの設定方法を説明します。シナリオの定義に関する網羅的な説明については、リファレンスを参照してください。

シナリオ更新画面 (編集後)

まず、Step 1. の上にある「Add step」ボタンをクリックして、削除リクエストの前にステップを追加します。

追加した Step のエンドポイント欄の「Select」ボタンをクリックし、作成リクエストを送信するエンドポイントを選択します。エンドポイントが多い場合には、検索欄にパスを入力して絞り込むと探しやすいでしょう。

エンドポイントを絞り込む

エンドポイントを選択したら、「Select」ボタンをクリックして選択を確定します。

次に、作成リクエストのレスポンスからリソースの ID を抽出し、削除リクエストに注入するための設定を入力します。ここでは作成時のレスポンスにおけるリソース ID が、ヘッダーに Location: /mypage/items?id=XXXX という形で記載されていると仮定します。このような場合では、Step 1. の YAML 入力欄に以下のような設定を入力し、抽出方法を指定します。

extractors:
- type: regex
part: header
name: id
group: 1
regex:
- 'Location: /mypage/items\?id=([a-z0-9]+)'

この設定により、Location: /mypage/items?id=XXXX の中の XXXX の部分が抽出され、id という名前の変数に値が格納されます。レスポンスの異なる部分を抽出したい場合には、リファレンスを参考に記述してください。

次に、Step 2. にて抽出した ID を注入するための設定を入力します。削除リクエストのボディ中の id パラメータに注入する場合の設定を以下に示します。

bindings:
- type: body
key: .id
extractorName: id

この設定により、先ほど抽出した id 変数の値が、削除リクエストのボディ中の id パラメータに設定されます。異なるパラメータに注入したい場合には、リファレンスを参考に、key の部分を適切なパラメータ名に置き換えてください。

tip

作成リクエストや削除リクエストにおいて CSRF トークン等が必要な場合には、CSRF トークンを抽出するためのステップの追加が必要です。「ログインが必要なアプリケーション」の節にて説明した CSRF トークンの抽出・注入方法やリファレンスを参考に設定してください。

以上の設定を入力したら、「保存」ドロップダウンをクリックし、「保存」を選択してください。

次に、Web 診断を実行する手順に進みます。