# 误报降级、业务影响验证标准与报告规范

> 本文件是 `src-vuln-hunting` 的 **confirmed 门闩**。  
> 与 `r/007.txt`（怎么留证据）、`r/018.txt`（报告骨架）、`r/016.txt`（提交合规）互补。  
> 本文件讲：**测完后怎么判断是不是真漏洞**，以及 **怎么出能过审的报告**。

**核心原则（全程默念）**：

```text
能调接口 ≠ 有漏洞
返回 200 ≠ 确认漏洞
无认证 ≠ 越权
返回数据 ≠ 信息泄露
```

**何时必读**：Phase4 准备把 finding 标 `confirmed` 之前；Phase5 写报告定级之前；被拒「危害不足/无法证明」时。

---

## 1. 误报根因分析

当前测试中反复出现的误报模式：

| 误报模式 | 典型表现 | 根因 |
|---------|---------|------|
| 无认证 = 漏洞 | API 无需 token 即标记为 confirmed | 未区分「公开/预授权接口」与「需保护接口」 |
| 前端可见 = 越权 | 页面功能可访问即视为越权 | 未理解业务设计意图 |
| 泛化响应 = 信息泄露 | 「系统异常」「成功」(空列表) 视为信息泄露 | 未检查响应是否含实际敏感数据 |
| 返回数据 = 信息泄露 | 字典接口返回数据即视为漏洞 | 未区分「业务公开/字典数据」与「内部敏感数据」 |
| 无认证退款 = 严重漏洞 | 仅验证「接口可调用」即标记 critical | 未验证真实退款/资金流是否可完成 |
| 接口可访问 = IDOR | 传入任意 userId 返回 200 即视为 IDOR | 未验证返回数据是否属于他人 |
| 密钥泄露 = 高危 | 获取到随机字符串即视为密钥泄露 | 未验证密钥是否可还原明文/用于实际攻击 |

---

## 2. 三层判定模型（confirmed 前强制）

每个 threat / finding 在标记 `confirmed`（或写入可提交报告）前必须过三层：

```text
第一层: 可达性 (Access)         → 能不能调到这个接口？
第二层: 脆弱性 (Vulnerability) → 调到之后能不能造成危害？
第三层: 可利用性 (Exploitability) → 危害是否真实可落地？
```

### 2.1 第一层：可达性（最外层，最弱证据）

- **判断**：接口返回 HTTP 200 / 业务 `code=0`（或等价成功）
- **典型误报**：仅验证到此层就标记 confirmed
- **通过条件**：只是进入下一层的门票，**不能**单独作为 confirmed 依据

### 2.2 第二层：脆弱性（核心判定层）

| 检查项 | 问自己 | 反例（不可 confirmed） |
|--------|-------|------------------------|
| 数据敏感性 | 返回的数据属于「不该给当前请求者看到」的吗？ | 公开字典、系统时间、空列表、卡号格式校验结果 |
| 操作危害性 | 这个操作能造成实际损失吗？ | 调了退款但订单不存在；创建订单但卡无效 |
| 身份依赖性 | 操作是否依赖特定用户的身份/权限？ | 任何人可查的公开信息、预授权前的检查接口 |

### 2.3 第三层：可利用性（确认攻击面）

| 类型 | 必须证明 |
|------|----------|
| 越权读 | 响应中确实包含**他人的**私有数据（姓名、手机号、余额、订单详情），不只是 userId 不同 |
| 越权写 | 操作后查询确认数据库/列表层面的值真的变了，不只是 `{"code":0}` |
| IDOR | 「对象 ID 是他人持有且非公开的」，且响应泄露了非公开信息 |
| 未授权操作 | 该操作不处于业务的「公开/预授权」阶段 |
| 密钥泄露 | 泄露的密钥可还原明文 / 用于签名伪造 / 用于解密数据 |

**规则**：只过第一层 → `suspicious` / 继续测；过第二层但第三层不足 → 降级或 `needs more proof`；三层全过才 `confirmed`。

---

## 3. 反向判定：什么不是漏洞

### 3.1 服务器随机密钥泄露 → 默认忽略

**例**：`POST /system/getServerRandomKey` → 每次不同的随机串

| 条件 | 结果 |
|------|------|
| 仅返回随机串，无法进一步利用 | ⛔ 不进漏洞清单，`info/ignore` |
| 可结合其他信息还原明文/签名 | ✅ 按实际危害评级 |
| 密钥固定/静态，可用于签名验证 | ✅ 按凭据泄露评级 |

检查清单：

```text
□ 密钥每次变化还是固定？ → 每次变化更倾向于不是漏洞
□ 能否用此密钥解密/还原实际数据？ → 不能 → 不是漏洞
□ 是否与具体用户/操作绑定？ → 不绑定 → 不是漏洞
```

### 3.2 图片验证码未授权获取 → 默认忽略

**例**：`GET /system/getImgCode/{userAccount}`

- 登录前必须可访问，属于标准预授权设计
- 获取验证码图片 ≠ 能自动识别 / 绕过登录

| 条件 | 结果 |
|------|------|
| 仅返回验证码图片 | ⛔ 正常业务，不进漏洞清单 |
| 验证码不刷新/可重用 | ✅ `验证码未刷新`，low |
| OCR 可识别且无频率限制 | ✅ `验证码强度不足+无频控`，按实际风险 |

### 3.3 字典/枚举值数据泄露 → 分级

| 条件 | 结果 |
|------|------|
| 仅业务分类代码和名称 | ✅ 信息泄露，**降级 low** |
| 含内部敏感字段（费率、密钥、白名单 IP） | ✅ medium~high |
| 含用户隐私（姓名、手机号、余额） | ✅ high~critical |

### 3.4 完整忽略清单

| 场景 | 原因 |
|------|------|
| 服务器随机密钥（每次变化，无法解密） | 无法验证实际危害 |
| 图片验证码获取 | 预授权，正常业务 |
| 系统时间 | 公开信息 |
| 空列表/空对象响应 | 无实际数据泄露 |
| 纯错误信息无敏感字段 | 无敏感数据 |
| 前端 UI 可访问 | 前端组件不视为越权 |
| 预授权接口仅返回校验结果 | 设计预期 |
| 格式校验结果（卡号/账号存在性） | 仅辅助信息；最多 low 枚举 |

---

## 4. 认证边界：预授权 vs 后授权

### 4.1 预授权（Pre-auth）— 无认证常是设计预期

典型：系统时间、卡号校验、公告、注册、验证码、前端加密用随机密钥、登录前必要接口。

**判断**：业务位置在「用户输入凭证/扫码/打开页面」之前 → 无认证 **不** 单独报未授权。  
**例外**：泄露其他用户敏感数据（IDOR）；或允许非预期写操作。

### 4.2 后授权（Post-auth）— 缺认证才是问题

典型：创建/退款订单、用户资料、我的订单列表、资金/积分写操作。

### 4.3 字典接口 `/pub/dict/*` 等

- 业务上：字典本身常不敏感，但暴露内部架构
- 安全上：缺认证 → 配置缺陷
- 评级：仅代码+名称 → **low**；含敏感配置 → medium+

---

## 5. 响应内容分级

### 5.1 降为 info / 不进清单

| 响应特征 | 处置 |
|---------|------|
| 纯错误无数据（系统异常） | 不进清单 |
| 空列表/空对象 | 不进清单 |
| 通用提示（订单不存在） | 不进清单 |
| 系统时间 / 验证码图 / 随机密钥无解密能力 | 不进清单 |
| 格式校验结果 / 公开规则提示 | 不进清单 |

### 5.2 可进清单但须谨慎评级

| 响应特征 | 说明 |
|---------|------|
| 差异错误可枚举状态 | 信息泄露，low/medium |
| 返回他人数据 | 确认归属后标记 |
| 返回业务凭据（支付链接/token/sign） | 确认有效期与用途 |
| 成功执行业务写操作 | **必须**确认库/列表真变更 |
| 字典泄露 | 默认 low，含敏感配置再升 |

### 5.3 必须验证业务影响才能 confirmed

| 场景 | 必须验证 | 不可仅凭 |
|------|----------|----------|
| 退款 | 退款进入对方账户/钱包/订单态真实变化 | `code=0` |
| 订单创建 | 订单以攻击者参数真实落库 | `code=0` |
| 数据修改 | 查询接口确认已变更 | 写入成功响应 |
| 越权读 | victim 视角数据一致 | 响应里 userId 不同 |
| 支付 | 资金/积分真实变动路径 | 支付页能打开 |
| 密钥泄露 | 可还原明文/签名/解密 | 拿到字符串本身 |

---

## 6. 常见误报场景速查

| 场景 | 判定 |
|------|------|
| A. 无认证但仅返回校验结果 | ❌ 不报「未授权」；✅ 可报差异枚举（low/medium） |
| B. 无认证返回空列表 | ❌ 不 confirmed；⚠️ 可 `suspicious`，换有效对象再证 |
| C. 随机密钥 | 默认 info/ignore；能解密/签名才报 |
| D. 验证码图 | 默认非漏洞；不刷新/无频控另论 |
| E. 字典数据 | 报则 **low**（架构暴露）；敏感配置再升 |
| F. 信息泄露过宽 | 无直接危害 → low；助攻其他攻击 → medium；直接资产损失 → high/critical |

---

## 6b. XSS 判定 SOP

confirmed 前三条件：

1. **输入确实进入 HTML/JS/CSS 上下文**  
   - 仅看 JSON 响应不够；须确认前端渲染（`innerHTML` vs `textContent`）
2. **转义是否被绕过**  
   - 至少试 3 个不同上下文姿势才可写「无法绕过」
3. **是否有实际执行环境**  
   - 反射需点击链路 → 通常 medium；存储自动执行 → high；盲 XSS 看触发面

**误报红线**：

| 场景 | 不能 confirmed 的原因 |
|------|----------------------|
| API 返回 JSON 未验证前端渲染 | 可能 `textContent` 无 XSS |
| 仅实体编码后未试属性上下文 | 上下文不同绕过不同 |
| 仅被 WAF 拦 | 记 `blocked`，不能确认后端安全 |
| 只测一种 `<script>alert(1)</script>` | 其他上下文可能可执行 |
| 滤了 script 未试事件处理器 | `onerror` 等不依赖 script 标签 |

`not_vulnerable` 时必填未排除面（属性上下文/存储/盲/DOM/编码/富文本白名单）。

---

## 6c. SSRF 判定 SOP

confirmed 前三条件：

1. **参数真被服务端用于出站请求**  
   - 内网内容回显 / 超时与无效 URL 差异 / 外部 OOB 回调
2. **目标/协议限制探测**  
   - ≥5 内网地址、≥3 协议、≥2 绕过技巧（在 RoE 内）
3. **业务影响真实**  
   - 云元数据/Redis/内网 Web/本地文件/盲扫 分级

**误报红线**：仅 `127.0.0.1` 返回 200 可能是「URL 已保存」；无时延差；未验证内网内容；只测一 IP 一协议。

| 利用方式 | 评级倾向 |
|---------|----------|
| 云元数据临时凭证 | critical |
| 内网 Redis 等可 RCE | critical |
| 内网管理后台 | high |
| 本地敏感文件 | medium |
| 盲 SSRF | medium |
| 仅能访问公开资源 | info / not_vulnerable |

`not_vulnerable` 时必填：DNS 重绑定、云元数据、file 协议、盲 OOB、非常用端口、302 绕过（均在授权内）。

---

## 7. confirmed 前 10 问（自检）

```text
□ 1. 预授权还是后授权？预授权无认证 ≠ 漏洞
□ 2. 响应里到底有什么敏感数据？空列表/时间/随机密钥/验证码图 → 不报
□ 3. 能实际读/改他人数据或资产吗？只能调通 → suspicious/not_vulnerable
□ 4. 前置条件（有效订单号/卡号/userId）是否可获取或可枚举？
□ 5. 「成功」是否真成功？查库/列表/二次读，禁止只看 code=0
□ 6. UI 上本来就能看到吗？前端本就展示 ≠ 越权；前端隐藏但接口返回才可疑
□ 7. 密钥/令牌能解密或伪造吗？不能 → 不是漏洞
□ 8. 枚举类：差异响应是否已用小字典抽样证明（遵守频控与 RoE）
□ 9. 弱口令：先确认无验证码/无频控，再小字典；禁止无脑全量爆破
□ 10. 字典与爆破：先决条件 → 再打；限速；命中写入证据包
```

爆破/枚举硬约束仍服从主 skill RoE：`r/016.txt` + `r/007.txt` 样本上限。

---

## 8. 报告书写规范（与 report-template 对齐）

### 8.1 落地位置

每次完成一轮可提交 finding，在工作区写出报告（二选一，保持项目一致即可）：

```text
reports/
  0x-title.md
evidence/
  01-baseline-req.txt
  ...

# 或（多项目并行时）
pentest-report/{project-id}/
  report.md
  evidence/
```

### 8.2 每个漏洞必须具备

1. **完整请求包**（原始 HTTP / Burp 风格）
2. **完整响应包**（状态码 + 证明危害的 body，脱敏）
3. **漏洞描述 ≥3 句**：是什么 / 为何违规 / 攻击者能做什么（业务影响）
4. **修复建议 ≥2 条**可操作措施
5. 建议附 **curl 复测命令**（无真实他人数据）

合格描述示例：

```text
该接口未进行任何身份认证即可查询任意用户的最近登录记录。
攻击者传入测试账号作为 userAccount 参数，即可获取完整登录信息，
包括 HMAC Salt、登录 IP、操作参数等敏感数据。
这些信息可用于后续签名伪造或社工（需另证链路时写清依赖）。
```

### 8.3 报告三块结构（一轮测试收尾时）

1. **漏洞详情**（每洞：包 + 描述 + 修复 + 复测）
2. **盲区清单**：`BLOCKED` / `NEEDS` / `N/A`（禁止「部分覆盖」「基本完成」）
3. **安全建议汇总**：紧急 / 高 / 常规

### 8.4 禁止措辞

| ❌ 禁用 | ✅ 应写成 |
|--------|----------|
| 未授权访问漏洞 | 具体：越权读 / 越权写 / 信息泄露 + 字段 |
| 任意用户订单查询 | 实际返回了哪些字段 |
| 可导致资金损失 | 除非已验证真实资金/积分变动 |
| 可导致信息泄露 | 列出具体泄露字段 |
| 密钥泄露 | 除非已验证可用于实际攻击 |
| 部分覆盖/基本完成/待后续验证 | `BLOCKED` / `NEEDS` / `N/A` |

### 8.5 单洞模板（可直接贴进 report-template）

```markdown
### [严重级别] [漏洞名称] — [评级]

**接口**: `[METHOD] [path]`
**认证要求**: [有/无]
**漏洞类型**: [具体类型]
**三层判定**: Access ✅ / Vulnerability ✅ / Exploitability ✅

**请求包**:
```http
...
```

**响应包**:
```http
...
```

**漏洞描述**：
（≥3 句：是什么 / 为何是洞 / 业务影响与攻击链）

**修复建议**：
1. ...
2. ...

**curl 复测**:
```bash
curl -sk -X METHOD -H "Content-Type: application/json" -d '...' "https://target/path"
```
```

### 8.6 等级调整速查

| 原标记 | 实际情况 | 调整后 |
|-------|---------|--------|
| Critical 未授权退款 | 仅接口可调，未证真实退款 | Suspicious 或降级，补证据 |
| High 未授权信息查询 | 空列表/通用错误 | Info / Low / 不报 |
| Medium 信息泄露 | 差异错误枚举 | Low，写清利用难度 |
| High 未授权访问 | 预授权设计 | Not Vulnerable |
| High 密钥泄露 | 随机串无法利用 | Info / Ignore |
| Medium 验证码接口 | 预授权正常 | Not Vulnerable |
| Medium 字典泄露 | 仅代码和名称 | Low |

---

## 9. 与主流程挂接

| 阶段 | 动作 |
|------|------|
| Phase4 Hunt | 出 PoC 后跑 §2 三层 + §7 十问；不过不写 confirmed |
| Phase5 Report | 用 §8 模板；措辞过 §8.4；定级过 §8.6 |
| Phase5 提交前 | 再过 `r/016.txt` + `r/007.txt` |
| 被拒「危害不足」 | 回到 §2.3 / §5.3 补业务影响证据，禁止硬抬级 |

---

## 10. 一句话门闩

```text
200 只是门票；敏感数据/真实状态变更才是门票后面的货。
货没拿到，不许叫漏洞；货拿到了，报告写清字段、归属和业务后果。
```