威胁建模:STRIDE与DREAD实战应用
威胁建模这东西,说白了就是帮你在开发阶段,把敌人可能从哪里打过来的路子都过一遍。我刚开始做安全的时候,总觉得脑子里过一遍就行,结果线上出了事才追悔莫及。后来吃过亏,才老老实实拿笔拿纸,或者用工具,把整个威胁面梳理清楚。
这一章,咱们重点聊聊两个经典框架:STRIDE 和 DREAD。STRIDE 负责“分类”——你可能会遇到什么样的威胁?DREAD 负责“打分”——哪个威胁最要命?二者配合,基本就能把风险的底摸清了。
STRIDE 威胁分类:六顶帽子看清风险
STRIDE 是微软提出的威胁分类法。我个人的习惯是,在产品设计评审会上,把这六个字母列出来,一个一个问团队:“我们的系统,会不会碰见这种事?”
| 威胁类别 | 威胁定义 | 举个实际例子 |
|---|---|---|
| S - 欺骗 (Spoofing) | 冒充他人身份访问系统 | 攻击者伪造 JWT 登录管理后台 |
| T - 篡改 (Tampering) | 非法修改数据或代码 | 中间人篡改 API 请求中的订单金额字段 |
| R - 否认 (Repudiation) | 用户否认自己的操作行为 | 用户说“我没发起这个转账”,但系统没有留日志 |
| I - 信息泄露 (Information Disclosure) | 敏感数据被未授权人员看到 | 用户手机号通过接口明文返回 |
| D - 拒绝服务 (Denial of Service) | 系统资源耗尽无法提供服务 | 恶意请求打满 MySQL 连接池 |
| E - 权限提升 (Elevation of Privilege) | 普通用户获得管理员权限 | 普通用户通过 API 参数修改获取 root 权限 |
小提示: 我记得在某个电商项目里,我们只关注了“信息泄露”和“篡改”,结果忘了“否认”这件事。后来用户投诉说订单被取消了,我们拿不出有效日志自证清白。从那以后,我会把 STRIDE 当成个 checklist,每轮评审都逐项过。
DREAD 风险评估:给威胁打个分
STRIDE 解决了“有什么威胁”的问题。但接下来呢?哪个威胁要先修?你想想看,如果手头有 20 个安全漏洞,但修复资源只有一周,你会怎么选?
我个人习惯用 DREAD 来算个分。DREAD 是一个简易的量化模型,每个维度从 1 到 10 打分,总分越高,风险越大。
| 评估维度 | 含义 | 1分 (低风险) | 10分 (高风险) |
|---|---|---|---|
| D - 损害潜力 | 一旦攻击成功,系统损失多大 | 影响单个用户非敏感数据 | 全站数据泄露或核心服务瘫痪 |
| R - 重现性 | 攻击者能稳定复现攻击吗 | 极度依赖特殊环境,很难复现 | 公开可用工具一键执行 |
| E - 可利用性 | 发起攻击的门槛高不高 | 需要内网权限+高级知识 | 有公开 POC,浏览器就能干 |
| A - 受影响用户 | 多少用户/系统会被波及 | 仅影响 1 个内部测试账号 | 所有注册用户 |
| D - 可发现性 | 攻击者发现这个漏洞的难度 | 必须要有源码审计 | 正常使用就能触发并暴露 |
使用原则: 我一般会对每个威胁单独打分,然后计算总分。通常总分超过 30 分的,我建议必须在本迭代内修复;20-30 分的可以放到下一个迭代;20 分以下的,我偏向放到安全债里持续跟踪。
实战威胁建模演练
光讲理论不够,咱们来走一个实际案例。我有一次做过一个订单系统的威胁建模。咱们就按这个场景,把 STRIDE 和 DREAD 串一遍。
第一步:确定评估范围
先画个简单的上下文图。我记得当时我拿白板画了“客户端 ⇄ 订单网关 ⇄ 订单服务 ⇄ 数据库”。边界在哪?用户输入是边界,数据库接口也是边界。
第二步:逐项应用 STRIDE
- 欺骗: 客户端的 可能被盗用。攻击者可以用 伪造任何用户下单。
- 篡改: 网关和订单服务之间的请求,如果没做签名,中间人可以修改商品或价格。
- 否认: 没有完整的审计日志。用户说“我没下单”,系统拿不出证据。
- 信息泄露: API 返回了过多字段,比如收货电话、支付流水号。
- 拒绝服务: 订单创建接口没有限流,可以被刷爆。
- 权限提升: 普通用户请求中携带 admin 参数,后端没校验就放行。
第三步:用 DREAD 给每个威胁打分
咱们拿“篡改”来举个例子。假如攻击者篡改了订单金额。
| 维度 | 评分 | 理由 |
|---|---|---|
| 损害潜力 | 8 | 修改金额可能直接造成经济损失 |
| 重现性 | 9 | 只要请求没做防篡改,每次都能改 |
| 可利用性 | 6 | 需要处在同网关网络段内,有一定门槛 |
| 受影响用户 | 10 | 所有下单的用户都可能受影响 |
| 可发现性 | 5 | 需要刻意抓包才能发现,普通用户难以察觉 |
总分:8+9+6+10+5 = 38分。这属于极高风险,必须立刻修复。
第四步:输出威胁矩阵与缓解措施
你可以把每个威胁的STRIDE类别、DREAD总分、以及对应的缓解措施整理成一份清单。比如针对上面的“篡改”,我就会加上“对订单核心字段做 HMAC 签名”或者“强制使用 HTTPS + 双向证书”。
第五步:制定缓解措施
拿上面那个“篡改”威胁来说,评分38,我翻了以前的真实案例,做了这样几件事——
- 在订单服务层给核心字段做 HMAC 签名校验
- 网关和订单服务之间使用 mTLS(双向证书)
- 全链路强制 HTTPS,并启用 HSTS 头部
注意避坑: 我曾经在实战中发现,团队容易追求“完美建模”。把所有威胁的DREAD都打到最低分才罢休,但这是不现实的。我个人的经验是,把明显的高于 30 分的威胁先干掉。剩下的,可以放到安全债里慢慢修。先堵住大洞,比追求无懈可击更重要。