2. 目标应用建模
DAST 的扫描质量,首先取决于我们是否把“被测系统”建模正确。很多团队把 DAST 简单理解为“输入一个 URL 然后点开始”,结果扫描器只爬到了首页和几个静态链接,真正的业务接口、单页应用路由、微服务网关后的服务全部漏掉。目标应用建模要解决的核心问题是:把用户能触达的每一个入口点、每一类参数、每一条业务流,转成扫描器可识别、可覆盖、可验证的对象清单。
一、从真实对象出发识别入口点
入口点(Entry Point)是外部输入进入应用的通道。建模时不要从“页面”出发,而要从“输入如何进入系统”出发。常见的真实对象包括:
- URL 路径与查询串:如
/product/detail?id=1024&from=search,路径段和查询参数都是注入、越权、SSRF 的候选点。 - HTML 表单:登录、注册、搜索、下单、上传,字段类型决定测试载荷(文本、文件、隐藏域、CSRF token)。
- REST/GraphQL API:路径参数、查询参数、JSON body、Header(Authorization、X-Forwarded-For)、Cookie。
- 单页应用(SPA)路由:
#/order/123或 history 模式下的/order/123,爬虫往往看不到,需要从 JS 中提取路由表。 - 微服务网关:网关暴露的聚合接口与后端服务接口可能不一致,网关层做鉴权、限流、路由重写,是攻击面收敛与放大的关键位置。
把这些对象整理成入口点清单时,建议至少记录:入口标识、协议方法、参数位置、参数类型、是否需要认证、所属业务域。下面这张图展示了从真实对象到攻击面清单的建模关系,以及各类入口在网关前后的分布。
二、入口点分类与参数建模
入口点分类不是学术分类,而是为了决定“用什么载荷、以什么身份、按什么顺序”去测。一个实用的分类维度是参数位置与数据语义的组合:
| 参数位置 | 典型示例 | 优先测试方向 |
|---|---|---|
| 路径段 | /user/1001/profile | 越权访问、ID 遍历、路径穿越 |
| 查询串 | ?q=test&page=1 | 反射型 XSS、SQL 注入、SSRF |
| JSON Body | {"role":"user"} | 参数篡改、批量赋值、类型混淆 |
| Header | X-Forwarded-For | IP 伪造、鉴权绕过、缓存投毒 |
| Cookie | sessionid=abc | 会话固定、JWT 篡改 |
| 文件字段 | avatar.png | 恶意文件上传、内容类型绕过 |
建模时还要标注参数的“可控性”和“回显性”。可控但无回显的参数适合盲注类测试;可控且有回显的参数适合 XSS 和模板注入。对于 SPA,需要从打包后的 JS 中提取路由表,例如在 app.js 中搜索 path:、component: 等关键字,把 /order/:id 这类动态路由还原成可访问的具体 URL。
三、业务流建模:把接口串成有状态的路径
单个接口测试通过,不代表业务流安全。业务流建模要回答:用户完成一个业务目标,需要按什么顺序调用哪些接口,携带什么状态。以电商下单为例,一条最小业务流是:
POST /api/v1/login → 获取 token
GET /api/v1/cart → 读取购物车
POST /api/v1/orders → 创建订单,返回 orderId
POST /api/v1/pay/{orderId} → 发起支付
GET /api/v1/orders/{id} → 查询订单状态
建模时记录每一步的输入、输出和状态依赖:orderId 来自上一步响应,token 来自登录。DAST 工具需要按这个顺序执行,才能覆盖“越权查看他人订单”“支付金额篡改”“订单状态跳变”等只有在有状态上下文中才暴露的问题。如果只对每个接口单独发请求,很多业务逻辑漏洞会被漏掉。
四、微服务网关下的攻击面收敛
在微服务架构中,网关是外部流量的统一入口,也是攻击面建模的关键节点。网关通常做三件事:路由转发、鉴权校验、限流熔断。建模时要区分两类接口:
- 网关暴露接口:如
/api/v1/orders,外部可直接访问,是 DAST 的主要目标。 - 内部服务接口:如
/order-service/internal/query,通常不对外暴露,但如果网关路由配置过宽(如/api/**全部转发),就可能被外部触达。
因此,建模阶段要拿到网关的路由配置(如 Spring Cloud Gateway 的 routes、Nginx 的 location、Kong 的 service/route),逐条核对“哪些前缀被转发到了哪个服务”。对于 GraphQL 网关,还要提取 schema 中的 Query 和 Mutation 字段,因为单个 /graphql 端点背后可能对应几十个可调用的操作。
/api/v0/ 接口。这些往往是攻击面清单中最容易被遗漏、也最容易出问题的地方。
五、攻击面清单的交付形态
建模的最终交付物是一份可被扫描器消费的攻击面清单。它不需要很复杂,但字段要完整、可执行。一个最小可用的清单条目应包含:入口 URL、HTTP 方法、参数名与位置、是否需要认证、所需角色、所属业务流、优先级。下面是一个示例条目:
{
"entry": "GET /api/v1/orders/{id}",
"params": [
{"name": "id", "in": "path", "type": "integer"},
{"name": "fields", "in": "query", "type": "string"}
],
"auth": true,
"role": "user",
"flow": "order-query",
"priority": "high"
}