threat-model:威胁建模与安全设计评审
一句话定位:在概要设计之后、详细设计之前把「谁会怎么打这个系统」想清楚, 并把结论变成详细设计里的鉴权列、字段约束与测试用例编号。不产出「建议加强安全性」这类句子。
输入门禁
| 必需 | 从哪来 | 缺了怎么办 |
|---|---|---|
SPEC_SOURCE(合格 SRS) |
dev/SRS/*.md |
回 dev-master 阶段 1;只有 PRD 时走 req-doc Step F |
| 模块划分与部署拓扑 | 阶段 3 hld-design 的概要设计 |
概要设计缺失时,至少要用户口述「有哪些服务、谁和谁通信、数据存哪」,并在产出里标「拓扑为口述,未成文」 |
| 角色与权限矩阵 | SRS 的角色章节 | 缺则先补——没有角色矩阵就做不了越权分析,这是本技能最值钱的部分 |
| 数据分级(哪些是敏感数据) | SRS 非功能章节/用户确认 | 缺则现场问一句:哪些字段属于个人信息、凭据、商业敏感 |
Step 1:资产、信任边界与数据流
- 列资产:数据(分级)、凭据与密钥、可用性本身、业务规则(如余额、库存、审核状态)
- 画数据流图:外部实体 → 进程 → 数据存储,标出信任边界(公网↔内网、前端↔后端、租户之间、
自有服务↔第三方)。图一律走
diagram-generator,禁止手绘 ASCII - 每条跨边界的流写清:谁发起、带什么凭据、传什么数据、走什么协议、对端如何验证
边界数量决定工作量:典型三端项目 5–8 条边界;一条都列不出来说明拓扑还没搞清楚,回 Step 0。
Step 2:逐边界过 STRIDE
对每条信任边界过六类威胁,检查项见 references/stride-checklist.md(进入本步时读它):
| 字母 | 威胁 | 典型问法 |
|---|---|---|
| S Spoofing | 冒充 | 对端身份怎么验证?token 从哪来、会不会被重放? |
| T Tampering | 篡改 | 参数/价格/状态能否被客户端改?完整性怎么保证? |
| R Repudiation | 抵赖 | 敏感操作有没有留痕?日志能不能被改? |
| I Information Disclosure | 信息泄露 | 越权读、错误信息带堆栈、日志带敏感字段、第三方外发 |
| D Denial of Service | 拒绝服务 | 无界查询、大文件、无限重试、缺限流 |
| E Elevation of Privilege | 权限提升 | 普通用户能不能拿到管理端能力?前端隐藏按钮是否等于后端校验? |
多租户/多角色系统必做一项:把权限矩阵的每个「否」格子当成一条待验证威胁—— 「按 id 查询时校验归属」要落到详细设计的每个接口上,不是写一句总则。
Step 3:滥用用例(攻击者视角)
每条留下来的威胁写成一条可执行的滥用用例,格式与功能用例对称,便于 pm-test-cases 直接接手:
AU-03 | 越权读取他人草稿
前置:用户 A 与用户 B 各有一篇未发布草稿
步骤:以 A 的会话调用 GET /api/posts/{B的草稿id}
预期:403,且日志记录一次越权尝试(不返回草稿内容,也不返回"不存在"以外的信息差)
Step 4:缓解措施回写(本技能的交付核心)
每条威胁必须落到一个具体位置,否则只是清单:
| 威胁去向 | 回写到哪 |
|---|---|
| 需要接口层强制 | 详细设计(lld-design)的接口表:鉴权要求列 + 数据范围列 |
| 需要字段约束 | 详细设计的表结构:唯一键、非空、长度、校验规则 |
| 需要非功能要求 | SRS 非功能章节:限流阈值、日志留存期、加密要求、脱敏规则 |
| 需要验证 | pm-test-cases 的用例编号(滥用用例进「安全/权限」分类) |
| 暂不处理 | 残余风险登记表(见 Step 5) |
硬规则:一条威胁 → 一条可验证缓解 + 一个测试用例编号。 写不出测试用例的缓解措施,说明它还不够具体。
Step 5:残余风险登记
不做的也要成文:风险描述、为什么不做(成本/阶段/概率)、影响面、触发后的应对、复核时间点、确认人。 「以后再说」不是理由;残余风险没有确认人时,默认挂给项目负责人并在交付说明里列出。
产出
dev/design/威胁模型-{项目}-V{版本}.md,结构:
## 一、范围与资产(含数据分级)
## 二、数据流图与信任边界(图由 diagram-generator 生成)
## 三、STRIDE 逐边界结果
| # | 边界 | 类别 | 威胁 | 可能性 | 影响 | 缓解措施 | 回写位置 | 用例编号 | 状态 |
## 四、滥用用例(AU-xx)
## 五、残余风险登记
## 六、复核记录(每次架构变更后回来更新)
硬规则
- 不写空话:「加强权限校验」「注意数据安全」不算一条;必须写成「哪个接口、加什么校验、怎么验」
- 不重复通用清单:只写这个系统的威胁;OWASP Top 10 逐条抄一遍没有价值
- 可能性×影响定优先级:高×高必须在阶段 7 之前落到设计里,不能留到上线审计
- 图走
diagram-generator,与其它设计文档一致 - 架构一变就复核:新增第三方依赖、新增外部入口、改鉴权方式 —— 回来更新第六节
在 dev-master 流程里的位置
挂 阶段 3(概要设计) 的 also:概要设计定完架构与部署拓扑后立刻做,结论作为阶段 4 详细设计的输入。
阶段 11 pm-ai-ship-audit 会反过来核对「威胁模型里的缓解措施,代码里到底做没做」——两者一前一后,不重叠。
门禁(进阶段 4 前):高×高威胁全部有缓解措施与回写位置;残余风险有确认人。