CodeRoad Map 程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。
由 程序员柏风 独立维护 · 关于作者
学习 更多
威胁建模
这一课你将能做到
用 STRIDE 模型对任何一个接口做威胁分类,列出至少 4 条真实威胁
画出本站的信任边界图(Trust Boundary),识别数据跨边界的关键点
给本站的 tracks API 做一次完整威胁建模:资产 → 威胁 → 控制 → 验证
为什么要学
写代码时我们想「这功能怎么实现」,威胁建模逼你换脑子:「这功能会被怎么滥用」。攻击者不按设计用系统——登录接口用来枚举账号,搜索接口用来拖库,找回密码用来劫持账户。提前把这些列出来,防御措施才能落地。
人话:威胁建模是「以攻击者视角写需求文档」。STRIDE 就是六类攻击的缩写:Spoofing(假冒)、Tampering(篡改)、Repudiation(抵赖)、Information Disclosure(信息泄漏)、Denial of Service(拒绝服务)、Elevation of Privilege(提权)。每一条对应你的一类防御。
先建立图像
本站信任边界图:
┌─────────── 信任边界 1: 公网/DMZ ───────────┐
│ 浏览器 ←──HTTPS──→ Nginx (443) │
│ ↓ 信任边界 2: DMZ/应用区 │
│ Spring Boot :8080 │
│ ↓ 信任边界 3: 应用区/数据区 │
│ MySQL :3306 Redis :6379 │
└─────────────────────────────────────────────┘
数据跨边界时最危险:
边界1: 用户输入进系统 → 校验、编码、鉴权
边界2: 应用访问数据库 → 最小权限、参数化查询
边界3: 应用访问缓存 → ACL、禁用危险命令
STRIDE 六类威胁速查:
字母 威胁 本站例子 对策 S Spoofing 假冒 伪造 JWT 冒称管理员 强签名+验签+短 TTL T Tampering 篡改 改请求参数把分数改成 100 服务端校验+签名 R Repudiation 抵赖 用户否认做过敏感操作 不可篡改的审计日志 I Info Disclosure 泄漏 报错堆栈暴露表结构 模糊错误信息+加密 D DoS 拒绝服务 脚本狂刷登录接口 限流+验证码+WAF E Elevation 提权 普通用户调到管理接口 RBAC+服务端鉴权
跟着做
步骤 1:列出资产和入口
以本站 tracks(课程)功能为例,建一张资产清单:
资产 价值 暴露入口
─────────────────────────────────────────────
用户密码哈希 高 /api/auth/login
用户进度数据 中 /api/progress/*
课程内容(track) 中 /api/tracks/*
管理后台权限 高 /api/admin/*
JWT 签名密钥 极高 无直接入口(环境变量)
数据库 极高 仅内网
步骤 2:画数据流图(DFD)标出信任边界
[用户] --(1)登录--> [AuthController] --(2)查库--> [MySQL]
| |
|--(3)带JWT请求--> [TrackController] --(4)写进度--> [MySQL]
| |
| --(5)读缓存--> [Redis]
|
X (1)(3) 跨边界1:不可信输入进入
X (2)(4) 跨边界2:应用访问数据层
步骤 3:逐条 STRIDE 过一遍 对 POST /api/progress/{trackId}/complete 这个接口:
S-假冒: 攻击者伪造他人 JWT?
→ 控制: RS256 强签名、密钥放 KMS、exp 30 分钟
→ 验证: 改 payload 一个字符,请求应 401
T-篡改: 攻击者把 trackId 改成未购买的课?
→ 控制: 服务端校验「当前用户有权访问该 track」
→ 验证: 用 A 的 token 提交 B 的私有 trackId,应 403
R-抵赖: 用户刷完成度领证书后否认?
→ 控制: 审计日志表(user_id, action, ip, ua, ts),WAL 级别持久化
→ 验证: 日志是否有独立写入权限,应用账号能否 UPDATE 日志表(应不能)
I-泄漏: 报错信息暴露 SQL/表结构?
→ 控制: include-stacktrace=never,统一异常处理
→ 验证: 制造 500,看响应是否只有 traceId
D-拒绝: 脚本 1 秒 1000 次提交?
→ 控制: Redis 滑动窗口限流(同用户 10 次/分钟),Nginx limit_req
→ 验证: ab -n 1000 压测,超过阈值的应 429
E-提权: 普通用户改 role 字段?
→ 控制: 注册接口 DTO 不含 role 字段;角色变更只走管理接口+审计
→ 验证: 注册请求带 "role":"ADMIN",入库应仍是 USER
步骤 4:输出威胁清单并排优先级 编号 威胁 可能性 影响 风险 控制状态
T01 JWT 伪造 低 高 中 ✅已控制(验签)
T02 水平越权改他人进度 高 中 高 ⚠️待修复
T03 登录接口爆破 高 中 高 ⚠️待加限流
T04 审计日志被应用账号删除 低 高 中 ❌待控制
排序规则:风险 = 可能性 × 影响。先修「高风险且便宜」的(T03 加个限流半小时),再排「高风险贵」的。
步骤 5:把控制转成开发任务 T03 → 任务: 登录接口加 Redis 限流
验收: 同 IP 第 6 次登录请求返回 429
负责人: 后端 截止: 本周五
T04 → 任务: 审计日志表禁止 UPDATE/DELETE
验收: 用应用账号执行 DELETE FROM audit_log 报权限错误
威胁建模的输出不是一份好看的文档,是一堆带验收标准的开发任务。
讲清楚要点
威胁建模在设计阶段做最便宜 :画图阶段发现「这个接口不需要存在」,删掉成本为零;上线后发现有越权洞,修复+数据排查+通报成本高百倍。新功能评审时花 30 分钟过一遍 STRIDE。
信任边界是建模的核心 :威胁集中在数据跨边界处——用户输入进系统、应用访问数据库、服务间调用。把边界画出来,每个边界问一句「这里数据可信吗」。
STRIDE 是检查清单不是学术模型 :不需要背理论,就把它当六问模板:这个功能能被假冒吗?能被篡改吗?操作能抵赖吗?数据会泄漏吗?能被刷垮吗?权限能提升吗?
风险排序,不是全部修 :资源永远不够。用「可能性×影响」排序,高危必修、中危排期、低危接受并记录(写清「已知风险,决定接受」)。
建模是持续过程不是一次性文档 :每次大功能上线、架构变更(如新增第三方回调)、出现同类安全事件后,都要回到威胁模型更新。
你可能会懵的地方
STRIDE 和 PASTA 什么区别?
STRIDE 是威胁分类法(六类威胁),轻量,适合开发团队每次功能评审用。PASTA 是七阶段完整流程(定义目标→技术范围→分解→威胁分析→漏洞分析→攻击建模→风险分析),重,适合大系统年度评估。中小团队用 STRIDE 就够。
威胁建模要安全团队才能做吗?
恰恰相反——最懂业务逻辑漏洞的是写代码的人。安全团队提供方法论和评审,开发团队主导建模。「谁会想刷这个接口」这种问题,开发比安全工程师更清楚。
建模产出是什么格式?
一张 DFD 图(带信任边界)+ 一张威胁清单表(威胁/可能性/影响/控制/验证方法/状态)。存在 Wiki 或代码库 docs/ 下,和功能代码一起演进。
多久做一次?
触发式而非周期式:新功能设计评审时、架构变更时、重大安全事件复盘时。不需要每月全量重做。
攻击树(Attack Tree)和 STRIDE 选哪个?
互补。STRIDE 横向覆盖(每类都想想),攻击树纵向深挖(从一个目标如「盗取用户数据」倒推所有可能路径)。关键资产用攻击树深挖,普通功能用 STRIDE 过一遍。
错法对照 错法 问题 正解 只在上线前做一次建模 设计缺陷发现太晚 设计评审时就做 建模输出是一份 PPT 没人执行 输出带验收标准的开发任务 试图修掉所有威胁 资源耗尽,高危反而没修 风险排序,低危显式接受 只考虑技术漏洞 业务逻辑漏洞(刷优惠/薅羊毛)漏掉 STRIDE 每条问「业务上怎么被滥用」 建模文档写完不更新 架构变了模型过时 随架构变更同步更新
卡点急救
团队觉得建模「太形式主义」推不动 :别从文档流程推,从一个真实漏洞复盘切入——「这个越权洞如果建模时问过 E 类问题就能发现」,用事故教育比制度推行有效十倍。
不知道可能性/影响怎么打分 :用三档即可(高/中/低),别纠结精确数值。参考:有公开 exploit=高可能性;涉及资金/账号接管=高影响。打分是为了排序,不是为了精确。
威胁清单太长不知道从何修起 :按「风险高 + 修复便宜」优先。加限流、改错误信息这种半天能修的先做;需要重构的(如补全审计体系)立项排期。
面试常问
什么是 STRIDE?
微软提出的威胁分类模型,六类:Spoofing 假冒(对策:认证)、Tampering 篡改(对策:完整性校验)、Repudiation 抵赖(对策:审计日志)、Information Disclosure 信息泄漏(对策:加密+最小暴露)、Denial of Service 拒绝服务(对策:限流+冗余)、Elevation of Privilege 提权(对策:授权+最小权限)。每类威胁对应一类经典防御控制。
威胁建模的流程是什么?
四步:① 建模——画数据流图,标出信任边界;② 识别——用 STRIDE 等框架逐边界列威胁;③ 评估——按可能性×影响排风险优先级;④ 缓解——为高危威胁设计控制措施并验证。产出是可执行的安全需求清单,而非文档本身。
举个你做过的威胁建模例子?
按本站场景答:对进度提交接口做 STRIDE 分析——识别出水平越权(改 trackId)、接口被刷(DoS)两个高风险项;控制:资源归属校验(trackId 必须在当前用户可见范围)+ Redis 滑动窗口限流;验证:越权请求返回 403、第 11 次/分钟请求返回 429。
自测三问
STRIDE 六个字母各代表什么?各自对应的经典防御是什么?
什么是信任边界?本站有几个关键信任边界?
威胁建模的输出物是什么?为什么「一份文档」不是合格的输出?
小结一句话 威胁建模就是以攻击者视角过一遍设计:画出信任边界,用 STRIDE 逐点提问,把答案转成带验收标准的防御任务——高危必修,低危接受。
延伸