用 Cloudflare Application Profiles 给 HTTP 请求加一道正向安全边界

2026-09-29 29 预计阅读时间: 1 分钟
来源: blog.cloudflare.com AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:8 分钟

当攻击者可以借助 AI 快速生成、改写和批量测试攻击载荷时,只依赖恶意特征、关键字或已知规则的防护方式会越来越吃力。Cloudflare Application Profiles 提供了另一种思路:学习正常 HTTP 请求的结构,并识别偏离这些结构的流量,为应用增加一层正向安全控制。

它并不是继续追问“这个载荷是否像攻击”,而是先回答“这个请求是否仍然像业务允许的请求”。

从拦截坏请求,转向定义好请求

传统负向安全模型通常寻找已知风险,例如 SQL 注入片段、脚本标签或异常编码。它对已知攻击很有效,但攻击者可以不断调整大小写、编码、字段位置和冗余内容,让载荷产生大量变体。

正向安全模型反过来描述应用预期接收的流量。以转账接口为例,正常请求可能具备以下结构:

  • 方法是 POST;
  • 路径是 /api/v1/transfers;
  • 请求体包含 amount、currency 和 beneficiary_id;
  • amount 是正整数;
  • currency 只接受有限的币种代码;
  • 不应出现业务从未定义的额外字段。

一旦请求偏离这些约束,例如突然增加 callback_url、把数字换成嵌套对象,或者提交异常复杂的结构,系统就可以将其识别为偏差。

Application Profiles 的价值在于学习实际 HTTP 流量结构,减少完全依靠人工枚举规则的负担。面对 AI 生成的大量载荷变体,结构边界通常比单个恶意字符串更稳定。

请求结构异常不等于攻击

结构偏差是高价值信号,但不能简单地把所有偏差都视为入侵。真实系统中经常存在这些情况:

  • 新版本客户端增加了可选字段;
  • 灰度发布期间同时存在两种请求格式;
  • 某些低频接口没有足够流量形成稳定基线;
  • 移动端、合作方和内部服务使用不同字段组合;
  • 合法请求结构正常,但业务语义仍然恶意,例如盗用凭据后的正常转账。

因此,正向安全应当与身份认证、授权、速率限制、WAF 规则和业务风控配合使用。它擅长缩小输入面,却不能判断用户是否真的有权执行某项操作。

更稳妥的落地方式是先观察偏差,再逐步执行拦截:

  1. 按主机名、API 版本和路径区分流量,避免把不同接口混成一个基线。
  2. 覆盖完整业务周期,包括批处理、月末任务和低频管理操作。
  3. 将偏差与应用日志、发布记录和客户端版本关联。
  4. 先处理高置信度异常,例如未定义字段、字段类型突变或明显异常的嵌套结构。
  5. 在 API 发布流程中同步更新安全策略,避免新版本被旧基线误伤。

用一个本地服务理解正向安全

下面的示例不是 Cloudflare 产品配置,而是一个可以本地运行的最小模型,用来展示“只接受已定义请求结构”的行为。运行前需要 Python 3.10 或更高版本。

python -m venv .venv
source .venv/bin/activate
pip install flask pydantic

保存为 app.py:

from typing import Literal

from flask import Flask, jsonify, request
from pydantic import BaseModel, ConfigDict, Field, ValidationError

app = Flask(__name__)


class CreateTransfer(BaseModel):
    model_config = ConfigDict(extra='forbid')

    amount: int = Field(gt=0, le=1_000_000)
    currency: Literal['CNY', 'USD', 'EUR']
    beneficiary_id: str = Field(pattern=r'^BEN-[0-9]{6}$')


@app.post('/api/v1/transfers')
def create_transfer():
    try:
        payload = CreateTransfer.model_validate(request.get_json(force=True))
    except ValidationError as exc:
        return jsonify({
            'error': 'request_shape_rejected',
            'details': exc.errors()
        }), 400

    return jsonify({
        'status': 'accepted',
        'transfer': payload.model_dump()
    }), 201


if __name__ == '__main__':
    app.run(host='127.0.0.1', port=5000, debug=False)

启动服务:

python app.py

发送符合预期结构的请求:

curl -i http://127.0.0.1:5000/api/v1/transfers \
  -H 'Content-Type: application/json' \
  -d '{"amount":1200,"currency":"CNY","beneficiary_id":"BEN-123456"}'

再发送一个带有额外字段和错误类型的请求:

curl -i http://127.0.0.1:5000/api/v1/transfers \
  -H 'Content-Type: application/json' \
  -d '{
    "amount":{"value":1200},
    "currency":"CNY",
    "beneficiary_id":"BEN-123456",
    "callback_url":"https://attacker.example/capture"
  }'

第二个请求会收到 400。这里没有检查 callback_url 是否出现在恶意情报中,也没有寻找特定攻击字符串;服务只是拒绝了合同之外的字段和类型。这正是正向安全的核心思路。

在真实环境中,可以保留应用自身的严格校验,并让 Cloudflare Application Profiles 在流量抵达源站之前识别结构偏差。边缘层负责减少明显异常流量,应用层仍然是最终的输入验证边界。

上线时重点检查什么

引入 Application Profiles 时,不要把目标设成“一次性封死所有异常”。更实际的目标是持续收紧攻击面,同时控制误报:

  • 是否为不同 API 版本保留了独立的结构预期;
  • 是否识别出动态字段、可选字段和低频合法请求;
  • 是否给发布、回滚和紧急变更预留了流程;
  • 是否能从告警追踪到具体路径、客户端和应用日志;
  • 是否保留源站参数校验,而不是把全部责任交给边缘层;
  • 是否继续使用认证、授权、限流和针对已知攻击的防护规则。

正向安全的优势不是提前知道所有攻击载荷,而是明确应用愿意接受什么。随着攻击者生成和变异载荷的成本持续下降,这种围绕正常请求结构建立的边界,会成为传统检测规则之外更稳定的一层防线。


相关推荐