Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

API で Vulnerability Scanner を設定する

最終更新 Markdown で表示Agent セットアップ

Cloudflare Vulnerability Scanner を使うと、Broken Object Level Authorization(BOLA)などの脆弱性について API エンドポイントを検査できます。このガイドでは、Cloudflare API で最初の脆弱性スキャンを実行する手順を説明します。

前提条件

次のものが必要です。

  • アカウント内に、少なくとも 1 つのゾーンがあること。
  • スキャン対象 API を記述した OpenAPI スキーマ。
  • 対象向けの API 認証情報。スキャナーは、BOLA 脆弱性を検査するために、異なるユーザーとして認証する必要があります。

手順

API トークンを作成する

API リクエストは、ベース URL https://api.cloudflare.com/client/v4/ を使い、Authorization ヘッダーの Bearer トークンで認証します。

対象アカウントに次の 権限 を持つ API トークンを、Cloudflare ダッシュボードで 作成 します。Account > API Gateway > Edit

以降のコマンドで使えるよう、API トークンと、Cloudflare ダッシュボードのアカウント Overview ページにある Account Tag を環境変数として保存します。

export CLOUDFLARE_API_TOKEN="<YOUR_API_TOKEN>"
export ACCOUNT_ID="<YOUR_ACCOUNT_ID>"

ターゲット環境を作成する

ターゲット環境は、スキャナーが何をスキャンするかを定義します。現在サポートしているターゲットタイプは zone だけです。

Cloudflare ダッシュボードのゾーン Overview ページで Zone Tag を確認し、エクスポートします。

export ZONE_TAG="<YOUR_ZONE_TAG>"

次の POST リクエストで、ターゲット環境を作成します。

cURL コマンドbash
curl "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/vuln_scanner/target_environments" \
  --header "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" \
  --header "Content-Type: application/json" \
  --data '{
    "name": "Production API",
    "description": "Main production zone for API scanning",
    "target": {
      "type": "zone",
      "zone_tag": "'"${ZONE_TAG}"'"
    }
  }'

レスポンスのターゲット環境 ID を、変数 TARGET_ENV_ID に保存します。

(任意)次の URL へ GET リクエストを送ると、ターゲット環境を確認できます。

https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/vuln_scanner/target_environments/${TARGET_ENV_ID}

credential set を作成する

現在、スキャナーは BOLA スキャンをサポートしています。次の 2 組の認証情報が必要です。

  • Owner:検査対象のリソースを所有する正当なユーザー。
  • Attacker:所有者のリソースへアクセスできないはずの、別の正当なユーザー。

スキャナーは両方のユーザーとして認証し、Attacker が Owner のリソースへアクセスできるかを確認します。各認証情報は、1 つ以上の credential を含む credential set にまとめます。

次の POST リクエストで、Owner の credential set と Attacker の credential set を作成します。

Owner の credential setbash
curl "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/vuln_scanner/credential_sets" \
  --header "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" \
  --header "Content-Type: application/json" \
  --data '{ "name": "Owner Credentials" }'

# Export the ID from the response
export OWNER_CRED_SET_ID="<OWNER_CRED_SET_ID>"
Attacker の credential setbash
curl "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/vuln_scanner/credential_sets" \
  --header "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" \
  --header "Content-Type: application/json" \
  --data '{ "name": "Attacker Credentials" }'

# Export the ID from the response
export ATTACKER_CRED_SET_ID="<ATTACKER_CRED_SET_ID>"

各 credential set に credential を追加する

credential は、スキャナーがリクエストに付与する、1 つの認証トークンまたはセッション値を表します。

次の POST リクエストで、Owner と Attacker の credential をそれぞれのセットへ追加します。

Owner の credential(Header)bash
curl "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/vuln_scanner/credential_sets/${OWNER_CRED_SET_ID}/credentials" \
  --header "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" \
  --header "Content-Type: application/json" \
  --data '{
    "name": "Owner Bearer Token",
    "location": "header",
    "location_name": "authorization",
    "value": "Bearer eyJhbGciOiJSUzI1NiIs...owner-token"
  }'
Attacker の credential(Cookie)bash
curl "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/vuln_scanner/credential_sets/${ATTACKER_CRED_SET_ID}/credentials" \
  --header "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" \
  --header "Content-Type: application/json" \
  --data '{
    "name": "Attacker Session Cookie",
    "location": "cookie",
    "location_name": "session_id",
    "value": "attacker-session-token-value"
  }'

(任意)次の URL へ GET リクエストを送ると、セット内の credential を一覧表示できます。

https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/vuln_scanner/credential_sets/<CRED_SET_ID>/credentials

スキャンを開始する

ターゲット環境と 2 つの credential set が用意できたら、BOLA スキャンを開始できます。

OpenAPI スキーマは文字列形式にします。たとえば jq を使います。

OPEN_API_SCHEMA=$(jq -c . < openapi.json)

次の POST リクエストでスキャンを開始します。

cURL コマンドbash
curl "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/vuln_scanner/scans" \
  --header "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" \
  --header "Content-Type: application/json" \
  --data "$(jq -n \
    --arg te_id "$TARGET_ENV_ID" \
    --arg schema "$OPEN_API_SCHEMA" \
    --arg owner "$OWNER_CRED_SET_ID" \
    --arg attacker "$ATTACKER_CRED_SET_ID" \
    '{
      target_environment_id: $te_id,
      scan_type: "bola",
      open_api: $schema,
      credential_sets: { owner: $owner, attacker: $attacker }
    }')"

レスポンスのスキャン ID を保存します。

export SCAN_ID="<SCAN_ID>"

スキャンの状態は、GET リクエストで確認できます。

cURL コマンドbash
curl "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/vuln_scanner/scans/${SCAN_ID}" \
  --header "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}"

スキャンレポートを取得する

スキャンの状態が completed になると、検査した脆弱性の詳細な検出結果を含むレポートを取得できます。

cURL コマンドbash
curl "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/vuln_scanner/scans/${SCAN_ID}" \
  --header "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}"

jq を使うと、レポート結果を要約しやすくなります。

curl "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/vuln_scanner/scans/${SCAN_ID}" \
  --header "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" | jq '.result.report.report.tests[] | {test_verdict: .verdict, steps: [.steps | to_entries[] | {step: (.key + 1), method: .value.request.method, url: .value.request.url, role: .value.request.credential_set.role, status: (if .value.errors | length > 0 then "error" else "ok" end)}]}'

jq コマンドを付けると、出力が要約されます。次の例では、ステップ 3 で Attacker が DELETE エンドポイントへアクセスできています。

{
	"test_verdict": "warning",
	"steps": [
		{
			"step": 1,
			"method": "POST",
			"url": "https://api.example.com/v1/orders",
			"role": "owner",
			"status": "ok"
		},
		{
			"step": 2,
			"method": "GET",
			"url": "https://api.example.com/v1/orders",
			"role": "attacker",
			"status": "ok"
		},
		{
			"step": 3,
			"method": "DELETE",
			"url": "https://api.example.com/v1/orders/bdc64e8a-deec-4374-92c0-4fe91d1650bb",
			"role": "attacker",
			"status": "error"
		}
	]
}

ポーリングの例

よくあるパターンは、スキャンが完了するまで状態をポーリングし、その後レポートを取得することです。

bash
while true; do
  STATUS=$(curl --silent \
    "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/vuln_scanner/scans/${SCAN_ID}" \
    --header "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" | jq -r '.result.status // empty')

  echo "Scan status: ${STATUS:-unknown}"

  case "$STATUS" in
    completed) echo "Scan finished. Fetching report..."; break ;;
    failed)    echo "Scan failed." >&2; exit 1 ;;
    *)         sleep 10 ;;
  esac
done

curl --silent \
"https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/vuln_scanner/scans/${SCAN_ID}/report" \
  --header "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" | jq .

制限

オープンベータ中は、大きな OpenAPI スペックがある場合、スキャナー向けにスペックを最適化した方がよいことがあります。

API のスキャン計画を作る AI モデルには、128k トークンのコンテキスト制限があります。ディスク上のファイルサイズでは、おおよそ 40〜60kB に相当します。スキーマがこのサイズを超える場合は、より小さいファイルへ分割する必要があります。

同様に、意味のあるユースケースごとに個別の OpenAPI ファイルを作ると、スキャン結果がより詳しくなることがあります。たとえば、アプリケーションがアカウント変更、ソーシャル共有、お気に入り登録をサポートしている場合、ベータ期間中はユースケースごとにスペックを分割すると、テストカバレッジが上がることがあります。


提供状況

Vulnerability Scanner は現在、Enterprise の API Shield お客様だけが利用できます。今後、Cloudflare はスキャンタイプを追加し、その時点でスキャナーの提供範囲を広げます。


リファレンス

credential の場所

credential を作成するとき、location フィールドは、スキャナーがリクエスト中に credential をどこへ付けるかを決めます。

Location location_name 使用例
header HTTP ヘッダー名 Bearer トークンを付けた Authorization ヘッダー。
cookie Cookie 名 セッショントークンを持つ session_id Cookie。

credential set には、複数の credential を含められます。たとえば、Authorization ヘッダーの Bearer トークンと、X-CSRF-Token ヘッダーの CSRF トークンの両方が必要な API では、セット内に 2 つの credential を設定します。

役に立ちましたか?