使用 Cloudflare 漏洞扫描器 (Vulnerability Scanner) 测试您的 API 端点是否存在漏洞,例如对象级别授权失效 (BOLA)。本指南介绍如何使用 Cloudflare API 运行您的第一次漏洞扫描。
您必须拥有:
- 账户中至少有一个区域 (zone)。
- 描述您要扫描的 API 的 OpenAPI 架构。
- 目标 API 凭据。扫描器需要以不同用户的身份进行身份验证,以测试 BOLA 漏洞。
所有 API 请求都使用基准 URL https://api.cloudflare.com/client/v4/,并在 Authorization 标头中通过 Bearer 令牌进行身份验证。
在 Cloudflare 仪表板中创建 API 令牌,并在目标账户的范围内指定以下权限:Account(账户) > API Gateway > Edit(编辑)
在 Cloudflare 仪表板中从您账户的 Overview(概述) 页面保存您的 API 令牌和账户 ID (Account Tag),并将其导出为环境变量,以便在以下命令中使用。
export CLOUDFLARE_API_TOKEN="<YOUR_API_TOKEN>"
export ACCOUNT_ID="<YOUR_ACCOUNT_ID>"目标环境定义了扫描器应该扫描的内容。目前,唯一支持的目标类型是区域 (zone)。
在 Cloudflare 仪表板中的区域 Overview(概述) 页面上找到您的区域 ID (Zone Tag) 并将其导出。
export ZONE_TAG="<YOUR_ZONE_TAG>"使用以下 POST 请求创建目标环境。
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}目前,扫描器支持 BOLA 扫描。这需要两组凭证:
- 所有者 (Owner):拥有被测试资源的合法用户。
- 攻击者 (Attacker):不应有权访问所有者资源的其他合法用户。
扫描器分别以这两个用户的身份进行身份验证,并检查攻击者是否可以访问所有者的资源。每组凭据组织成一个包含一个或多个凭据的凭证集 (credential set)。
使用以下 POST 请求创建一个所有者凭证集和一个攻击者凭证集。
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" }'
# 从响应中导出 ID
export OWNER_CRED_SET_ID="<OWNER_CRED_SET_ID>"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" }'
# 从响应中导出 ID
export ATTACKER_CRED_SET_ID="<ATTACKER_CRED_SET_ID>"凭据描述了扫描器附加到其请求中的单个身份验证令牌或会话值。
使用以下 POST 请求向每个集合中添加所有者和攻击者的凭据。
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"
}'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 请求来列出集合中的所有凭据。
https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/vuln_scanner/credential_sets/<CRED_SET_ID>/credentials准备好您的目标环境和两个凭据集后,您就可以开始 BOLA 扫描。
确保您的 OpenAPI 架构已格式化为字符串。例如,使用 jq。
OPEN_API_SCHEMA=$(jq -c . < openapi.json)使用以下 POST 请求发起扫描。
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 "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/vuln_scanner/scans/${SCAN_ID}" \
--header "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}"一旦扫描状态变为 completed,报告就可用,其中包含所测试漏洞的详细发现。
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 中成功访问了 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"
}
]
}一种常见的模式是轮询扫描状态直至其完成,然后获取报告。
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 文件,来获得更彻底的扫描结果。例如,如果您的应用程序支持账户修改、社交分享和个人收藏,那么在测试版期间,将您的规范拆分为针对这些用例的多个文件可能会提高测试覆盖率。
漏洞扫描器目前仅适用于订阅了 API Shield 的企业版客户。Cloudflare 将在未来添加更多扫描类型,并届时增加扫描器的可用性。
创建凭据时,location 字段确定扫描器在请求期间将凭据附加在何处。
| 位置 | location_name |
示例用例 |
|---|---|---|
| header | HTTP 标头名称 | 带有 Bearer 令牌的 Authorization 标头。 |
| cookie | Cookie 名称 | 带有会话令牌的 session_id cookie。 |
一个凭据集可以包含多个凭据。例如,如果一个 API 既要求在 Authorization 标头中传递 Bearer 令牌,又要求在 X-CSRF-Token 标头中传递 CSRF 令牌,则在其集合中将配置两个单独的凭据。