Contents
1 前言
在Cloudflare仪表盘的”安全性”选项卡下,有一个”API Shield(API防护)”的功能:

这个功能一看就是专门用来保护API的,不过之前我也没有自建的、需要保护的API,所以也没机会白嫖研究这个功能。
但是,随着最近这段时间我写了2篇涉及自建API的文章(参见家庭数据中心系列 构建高效且安全的随机图片API:Cloudflare Worker + R2 + KV 实战指南和家庭数据中心系列 Cloudflare Worker + KV:打造 WordPress 云端文章阅读统计),忽然发现我已经具备研究这个功能的素材了,这周的研究目标就选”API Shield”吧。
注:最近Cloudflare已经推出了新的仪表盘,功能布局变化非常之大,就比如这个”API Shield”功能,在新的仪表盘中叫”Web资产”:

不过为了兼容之前我写的Cloudflare相关的文章,我还是使用的老的仪表盘来截图。
2 设置步骤
2.1 添加终结点
2.1.1 什么是终结点以及创建终结点的目的
在 Cloudflare 的 API 保护中,”终结点”(Endpoint)指的是一个 API 的具体访问入口及访问方式,例如我之前在搭建云端文章阅读统计时使用”/views-track”作为记录文章阅读次数以及查询阅读次数的API入口。
终结点的核心在于明确 API 的正常访问范围,包括允许的请求路径、请求方法(如 GET、POST等)、来源(如特定的 IP 或域名)以及预期的访问模式。通过定义这些规则,Cloudflare 能够识别哪些是符合业务逻辑的正常请求,哪些可能属于异常或恶意流量,从而建立一个清晰的访问边界,为后续的流量监控、滥用检测和防护策略奠定基础。例如,如果某个终结点本应只接受 POST 请求,但出现了大量的 GET 请求,这可能就是潜在的滥用行为。
2.1.2 终结点的3种添加方式
在”终结点管理”-“添加终结点”部分,可以进行终结点的添加:

Cloudflare 提供了 3 种终结点的添加方式:手动添加、上传架构、从 Discover 中选择:

- “手动添加”适用于需要精确定义 API 终结点的情况,用户可以自行输入路径、请求方法(不包括请求细节)等信息;
- “上传架构”则支持导入 OpenAPI(Swagger)等标准化 API 规范文件,使得批量管理多个终结点更加高效;
- “从 Discover 中选择”这种方式仅适用于”Enterprise 版用户”,该方式能够自动发现活动 API,并基于实际流量分析生成终结点建议,帮助用户更轻松地管理 API 保护规则。
由于我不是尊贵的”Enterprise 版用户”,所以本文只涉及”手动添加”以及”上传架构”2种添加终结点的方式。
2.1.3 “手动添加”终结点实操
这节内容就以我的家庭数据中心系列 Cloudflare Worker + KV:打造 WordPress 云端文章阅读统计文章中的Worker代码实现的API为例进行添加了,具体的Worker代码如下:
export default {
async fetch(request, env) {
const url = new URL(request.url);
// 处理 GET 请求 -> 查询阅读次数
if (request.method === "GET" && url.pathname === "/views-track") {
return await handleGetRequest(url, env);
}
// 处理 POST 请求 -> 记录并返回最新阅读次数
if (request.method === "POST" && url.pathname === "/views-track") {
return await handlePostRequest(request, env);
}
return new Response("Invalid request", { status: 405 });
}
};
// 处理 GET 请求 -> 查询 KV 获取阅读量
async function handleGetRequest(url, env) {
const slug = url.searchParams.get("slug");
if (!isValidSlug(slug)) {
return new Response("Invalid slug format", { status: 400 });
}
const kvKey = `views:{slug}`;
const currentViews = parseInt(await env.views_kv.get(kvKey)) || 0;
return new Response(JSON.stringify({ success: true, views: currentViews }), {
headers: jsonHeaders(),
});
}
// 处理 POST 请求 -> 记录阅读量
async function handlePostRequest(request, env) {
try {
const { slug } = await request.json();
if (!isValidSlug(slug)) {
return new Response("Invalid slug format", { status: 400 });
}
const kvKey = `views:{slug}`;
const currentViews = parseInt(await env.views_kv.get(kvKey)) || 0;
await env.views_kv.put(kvKey, (currentViews + 1).toString());
return new Response(JSON.stringify({ success: true, views: currentViews + 1 }), {
headers: jsonHeaders(),
});
} catch (error) {
console.error("Worker Error:", error);
return new Response("Internal Server Error", { status: 500 });
}
}
// 校验 slug 格式
function isValidSlug(slug) {
return slug && /^[a-z0-9-]{1,100}$/.test(slug);
}
// 统一 JSON 响应头
function jsonHeaders() {
return {
"Content-Type": "application/json",
"Cache-Control": "no-store",
"CF-Cache-Status": "BYPASS",
};
}
从上面的代码中,可以看到这个API的访问路径为”/views-track”,方式有GET请求(用于查询文章阅读量)和POST请求(用于记录阅读量),而主机名由Worker的URL路由入口决定,就是我的博客的域名:”blog.tangwudi.com”,所以终结点的最终配置如下:

然后,就可以看到创建的终结点的访问情况:

还能进一步查看详细内容:

注1:API Shield 的终结点主要用于定义 API 的已知请求(方法 + 路径 + 主机名),然而,它本身并不会自动拦截未匹配的请求方式,例如,即使某个终结点仅添加了 GET 请求,POST 请求仍然不会被 API Shield 直接阻止,必须借助后续的 “失败设置”关联的WAF自定义规则来进行限制。
注2:”手动添加”的终结点目前仅定义了 API 的请求方法(如 GET/POST)和路径,但并未限制具体的请求内容格式,因此仍然存在一定的滥用风险。例如,在 GET 请求中,API 预期的格式是 /views-track?slug=xxx,但攻击者可能发送 /views-track?slug=随便写点垃圾数据,导致系统处理无效数据或浪费资源;而在 POST 请求中,API 预期的请求体结构是 { “slug”: “xxx” },但攻击者可能提交 { “slug”: 123 }、{ “random_field”: “hacker” },甚至是空 body,可能触发错误或试图绕过限制。因此,仅依赖”手动添加”的终结点并不足以定义完全符合要求的API请求格式,真要较真,还需要通过”架构验证”或者WAF自定义规则来限制请求内容。
注3:对于使用 WordPress 建站的用户,建议在API Shield终结点中也添加”/wp-admin/admin-ajax.php”这个路径(请求方式选择POST),因为许多主题和插件(如 Rank Math SEO、WooCommerce、Lazy Load 图片插件等)都会依赖该接口进行 AJAX 交互;此外,如果网站涉及前端交互,如点赞、评论加载、表单提交或异步数据获取,admin-ajax.php 也是必不可少的,而这些操作绝大部分都是使用POST的请求方式。
2.1.4 “架构验证” + “上传架构”(可选但是强烈建议)
2.1.4.1 架构验证的优势
架构验证并不是 API Shield 的必选项,但在采用 “上传架构” 方式导入 OpenAPI(Swagger)等标准化 API 规范文件时,它能提供比 手动添加终结点 更精细的 API 保护。
我在前文中已经讲过,手动添加的终结点仅定义 API 允许的 路径 + 方法,但不会限制具体的 请求参数、请求体结构和数据类型,这意味着攻击者仍然可以发送畸形数据,从而影响系统稳定性或消耗资源。
而架构验证则会严格校验 API 请求是否符合 预期格式,如 “slug” 字段必须是字符串,不能为整数;也不能缺少必需字段或包含不相关的字段。如果 API 提供方和调用方都遵循 OpenAPI 规范,架构验证还能确保数据结构一致,避免因参数格式错误导致的兼容性问题,提高 API 的稳定性和维护性。
此外,架构验证还能与 API Shield 的 “失败设置” 及 WAF 规则结合使用,不仅限制 请求路径和方法,还能在字段、数据类型和结构 层面对请求进行校验:如果启用了 “失败设置”,未注册的 API 请求会被 WAF 规则拦截,而架构验证则确保已注册 API 的请求格式符合预期,从而进一步增强 API 保护。
所以,如果 API 采用标准化的 OpenAPI 规范并希望对请求格式进行严格校验,启用架构验证将大大提升安全性;但如果 API 没有使用标准规范,则架构验证并非必需的步骤,这时可以通过 WAF 自定义规则来筛查请求内容。
要使用架构验证,需要符合OpenAPI规范的API架构描述文件,以我的云端文章统计”/views-track”这个API为例,其架构描述的yml格式文件内容如下,供大家参考:
openapi: 3.0.3
info:
title: Views Tracking API
description: API for tracking and retrieving article view counts.
version: 1.0.0
servers:
- url: https://blog.tangwudi.com
description: Production server
paths:
/views-track:
get:
summary: Retrieve the view count of an article
description: Fetches the current view count for a given article slug.
parameters:
- name: slug
in: query
required: true
schema:
type: string
pattern: "^[a-z0-9-]{1,100}"
responses:
"200":
description: Successfully retrieved the view count.
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
example: true
views:
type: integer
example: 123
"400":
description: Invalid slug format.
"405":
description: Invalid request method.
post:
summary: Increment the view count of an article
description: Increments the view count for a given article slug.
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
slug:
type: string
pattern: "^[a-z0-9-]{1,100}"
responses:
"200":
description: Successfully updated the view count.
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
example: true
views:
type: integer
example: 124
"400":
description: Invalid slug format.
"500":
description: Internal Server Error.
"405":
description: Invalid request method.
将以上内容保存为”views-track.yml”文件,后面实操的时候会用到。
另外,umami的服务端API、随机图片API都可以使用架构验证来进行防护。以umami为例,根据其官方文档中对API的描述,其对应的API架构文件内容如下(yml),有需要的朋友可以直接使用(servers部分的url需要按照自己网站进行修改):
openapi: 3.0.1
info:
title: Umami Tracking API
description: API definition for Umami event tracking.
version: 1.0.0
servers:
- url: https://umami.tangwudi.com/api
paths:
/send:
options:
summary: Preflight request for CORS
description: This allows browsers to check allowed methods before sending data.
responses:
"204":
description: No content, preflight request successful.
post:
summary: Send tracking data
description: Send analytics events and page views to Umami.
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
type:
type: string
enum: [event, pageview]
description: Type of tracking data.
payload:
type: object
description: Tracking payload containing event details.
properties:
website:
type: string
description: Website UUID.
hostname:
type: string
description: Hostname of the site.
screen:
type: string
description: Screen resolution of the client.
language:
type: string
description: Language of the client browser.
title:
type: string
description: Page title.
url:
type: string
description: Page URL.
responses:
"200":
description: Tracking data received successfully.
"400":
description: Bad request, invalid payload.
"403":
description: Forbidden request.
"500":
description: Internal server error.
2.1.4.2 “架构验证” + “上传架构”实操
1、启用架构认证
初始时架构认证默认是禁用的,需要启用架构认证:

2、上传架构
在”API Shield”-“设置”中,上传”views-track.yml”架构文件:



然后在”已上传的架构”部分已经可以看到上传的架构:

这时在架构验证部分可以看到”/views-track”后的可用架构部分已经变成了”views-track.yml”,同时还能看到24小时内有多少不合规的请求:

2.2 失败设置
前文说过,终结点部分仅仅是简单的定义API 允许的 路径 + 方法,它本身并不会自动拦截未匹配的请求方式。要实现对未匹配请求方式的拦截,则需要依靠”失败设置”部分创建的WAF自定义规则:

按如下步骤在”失败设置”关联WAF自定义规则:



加上”admin-ajax.php”的规则后如下:

注1:失败设置默认不会自动关联 WAF 自定义规则:如果首次添加终结点是采用手动添加方式,则需要根据模板手动创建失败规则;如果首次是通过上传架构文件的方式创建终结点,Cloudflare 会自动生成对应的失败规则。
注2:在 WordPress 里,除了 “/wp-admin/admin-ajax.php” 这个最常用的 API 之外,还有 “/wp-json/* “这个 API,它的作用是 提供基于 REST 的数据交互接口,使插件、主题以及外部应用可以通过标准的 HTTP 请求(如 GET、POST、PUT、DELETE)访问和操作 WordPress 的内容,例如获取文章、提交评论、用户认证等。不过,相较于 “admin-ajax.php”,”/wp-json” 并不算很常用,因为许多插件和主题仍然依赖传统的 AJAX 方式进行数据交互,而 REST API 主要在开发自定义应用或外部集成时才会被频繁使用。此外,部分站点出于安全考虑,可能会禁用 “/wp-json” 以减少暴露的 API 接口(比如我),所以我没有把这个API加入示范配置,对于需要这个API的朋友,需要考虑终结点和失败设置中的相关配置。
2.3 验证
使用curl命令构造除了GET和POST以外方式的请求来验证”API Shield”设置的策略是否生效,如果生效,预期的结果是403 Forbidden响应,并且在Cloudflare仪表盘WAF的”失败规则”应该有相应的被阻止的请求记录。
1、使用PUT请求方式:
curl -X PUT "https://blog.tangwudi.com/views-track" -i

然后在Cloudflare WAF自定义规则的”失败规则”进行确认,是否有命中的访问请求:

2、使用DELETE请求方式:
curl -X DELETE "https://blog.tangwudi.com/views-track" -i

然后在Cloudflare WAF自定义规则的”失败规则”进行确认,是否有命中的访问请求:

验证成功。
2.4 其他安全配置
Cloudflare 推出 “API Shield” 功能的目的就是对现有的 API 进行安全防护:预先定义合法的 API 访问方式,然后通过允许合法的访问,对不合法的访问按照事先设置的方式(失败规则)进行处理,来达到保障合法的 API 访问请求的目的。
但是,API访问的保障手段并不只有 “API Shield” 这一种,还有比如速率限制、WAF 自定义规则(通过 Referer 等条件)等方式,所以,在实际应用中,API 保护往往是多种手段结合使用的。例如,速率限制可以防止恶意用户频繁访问 API,避免资源滥用,而 WAF 自定义规则可以基于特定请求特征(如 Referer、User-Agent、IP 地址等)进行拦截,阻止未授权或异常流量。
除此之外,还可以结合 Cloudflare 的 Bot 管理功能,来识别并拦截自动化爬虫或恶意攻击脚本,进一步减少 API 被滥用的风险。同时,利用 mTLS(双向 TLS 认证)或 API Token 进行身份验证,也可以在源头上确保 API 访问的合规性。
因此,在实际场景下,单独使用 “API Shield” 并不能覆盖所有 API 防护需求,而是需要结合其他手段,形成一个完整的 API 安全防护体系,以最大程度地减少 API 被滥用的风险,同时保证正常业务流量的稳定访问。
3 扩展知识:F5 分布式云机器人防御
无意中看到了F5也有解决方案来保护用户的API(原文地址如下:使用 F5 分布式云机器人防御保护您的 Cloudflare CDN 部署),因为感兴趣顺便研究了一下:



总的来说,F5 的方案是利用 Cloudflare Worker 进行 API 保护,主要是通过 Worker 拦截 API 请求,然后转发到 F5 的 API 保护系统进行分析和验证,最后根据F5 API返回的结果来决定是放行、阻断还是挑战。大致流程如下:
1、当 API 请求进入 Cloudflare Worker 时,Worker 负责拦截流量,并提取请求头、请求体等关键信息。这一步的目的是在请求到达源站 API 之前,先进行初步处理,以便后续安全检测能够更精准地识别风险。
2、随后,Worker 会将提取出的请求数据发送到 F5 的 API 保护系统。F5 负责对这些数据进行深入分析,例如识别请求是否来自自动化 Bot、检测恶意流量,或者验证请求中的 Token 是否有效。通过这些检查,F5 可以判断该请求是否符合安全标准。
3、最后,Worker 会根据 F5 返回的分析结果来决定如何处理请求:如果 F5 认为请求是合法的,Worker 就会将其正常转发到源站 API;但如果 F5 认定该请求是恶意流量,Worker 便会直接返回 403 状态码,或者根据自定义规则返回特定的响应,以保护 API 免受攻击。
简单来说,如果有钱,并且 API 访问量大,且需要 AI 级别的防护,可以用 Worker + F5;如果没钱,Cloudflare API Shield其实也勉强够用了(了不起把架构验证利用上)。
Cloudflare Worker 在这个方案中并不负责复杂的安全分析,而是充当一个代理的角色。它的主要工作包括拦截 API 请求,收集必要的数据后,将其发送到 F5 进行安全检测,并根据 F5 的判断决定是否放行请求或直接拦截。Worker 本身并不执行深入的安全分析,而是依赖 F5 的安全能力来完成这一任务。
之所以选择基于 Worker 来实现,是因为 Cloudflare WAF 只能基于预定义的规则来阻挡请求,缺乏更灵活的决策能力。而 Worker 则可以进行更复杂的判断,比如识别 Bot 行为、分析用户行为模式等。此外,F5 的 API 保护能力比 Cloudflare WAF 更强,但 F5 并不能直接保护托管在 Cloudflare 之上的 API。因此,Worker 在这里作为一个中间层,既能确保 API 受到 F5 的安全防护,又能在 Cloudflare 的边缘网络上实现更智能的流量管理。
4 总结
其实,严格来说,API Shield 的核心功能(如仅允许特定请求方法、特定路径、速率限制等)都可以用WAF 自定义规则和速率限制等功能搭配来实现。比如:
• 限定请求方法:WAF 规则可以匹配 http.request.method,只允许 GET 或 POST。
• 限定请求路径:WAF 规则可以匹配 http.request.uri.path,确保 API 访问符合预期。
• 限定请求来源:可以基于 referer 或 ip 设置规则,防止未授权访问。
• 速率限制:Cloudflare 也提供 WAF 的 速率控制,类似 API Shield 的部分防护。
而API Shield 的优势在于,它把 API 保护功能模块化、可视化,对于有大量 API 需要管理的场景,API Shield 可以减少手动维护规则的工作量,并且结合mTLS(客户端证书验证)进一步提升安全性。
所以如果你的 API 保护需求比较简单,WAF 自定义规则就足够了,但如果是大规模 API 保护或者有更严格的安全要求,API Shield会让你更省心。