Skip to content
Cloudflare Docs

Configure Vulnerability Scanner via the API

Use Cloudflare Vulnerability Scanner to test your API endpoints for vulnerabilities such as Broken Object Level Authorization (BOLA). This guide explains how to run your first vulnerability scan using the Cloudflare API.

Prerequisites

You must have:

  • At least one zone in the account.
  • An OpenAPI schema describing the API you want to scan.
  • API credentials for your target. The scanner needs to authenticate as different users to test for BOLA vulnerabilities.

Process

Create an API token

All API requests use the base URL https://api.cloudflare.com/client/v4/ and authenticate with a Bearer token in the Authorization header.

Create an API token in the Cloudflare dashboard with the following permissions scoped to the target account: Account > API Gateway > Edit

Save your API token and Account Tag from your account's Overview page in the Cloudflare dashboard as environment variables to use in the following commands.

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

Create a target environment

A target environment defines what the scanner should scan. Currently, the only supported target type is zone.

Find your Zone Tag on the zone's Overview page in the Cloudflare dashboard and export it.

Terminal window
export ZONE_TAG="<YOUR_ZONE_TAG>"

Use the following POST request to create the target environment.

cURL command
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}"'"
}
}'

Save the target environment ID from the response into a variable TARGET_ENV_ID.

(Optional) You can verify your target environment by making a GET request to the following URL.

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

Create credential sets

Currently, the scanner supports a BOLA scan. This requires two sets of credentials:

  • Owner: A legitimate user who owns the resources being tested.
  • Attacker: A different legitimate user who should not have access to the owner's resources.

The scanner authenticates as both users and checks whether the attacker can access the owner's resources. Each set of credentials is organized into a credential set containing one or more credentials.

Use the following POST requests to create an Owner credential set and an Attacker credential set.

Owner credential set
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 set
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>"

Add credentials to each credential set

A credential describes a single authentication token or session value that the scanner attaches to its requests.

Use the following POST requests to add the owner and attacker's credentials to each set.

Owner's credential (Header)
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's credential (Cookie)
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"
}'

(Optional) You can list all credentials in a set using a GET request to the following URL.

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

Start a scan

With your target environment and two credential sets ready, you can start a BOLA scan.

Ensure your OpenAPI schema is formatted as a string. For example, using jq.

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

Use the following POST request to initiate the scan.

cURL command
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 }
}')"

Save the scan ID from the response.

Terminal window
export SCAN_ID="<SCAN_ID>"

You can check the status of your scan using a GET request.

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

Retrieve the scan report

Once a scan has status completed, a report is available containing detailed findings for the vulnerabilities tested.

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

You may find it easier to summarize the report results with jq.

Terminal window
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)}]}'

Adding the jq command will summarize the output. In the following example, the attacker successfully accessed the DELETE endpoint in step 3.

{
"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"
}
]
}

Example polling pattern

A common pattern is to poll the scan status until it completes, then fetch the report.

Example
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 .

Limitations

During the open beta, if you have large OpenAPI specs, you may want to optimize your specs for the scanner.

The AI model used to build a plan for scanning your API has a 128k token context limit. This approximates to 40 to 60kB of file size on disk. If your schema is larger than this size, you may need to split your schema into smaller files.

Similarly, you may see more thorough scan results by creating individual OpenAPI files by semantic use case. For example, if your application supports account modification, social sharing, and personal favoriting, splitting your spec into multiple files per these use cases may show increased test coverage during the beta.


Availability

The vulnerability scanner is currently only available for Enterprise API Shield customers. Cloudflare will add more scan types in the future and increase the availability of the scanner at that time.


Reference

Credential locations

When creating credentials, the location field determines where the scanner attaches the credential during requests.

Locationlocation_nameExample use case
headerAn HTTP header nameAuthorization header with a Bearer token.
cookieA cookie namesession_id cookie with a session token.

A credential set can contain multiple credentials. For example, an API that requires both a Bearer token in the Authorization header and a CSRF token in the X-CSRF-Token header would have two separate credentials configured in its set.