威胁建模:STRIDE模型、数据流图(DFD)绘制、威胁识别与风险评估

威胁建模这件事,说白了就是在攻击者动手之前,先替他们想好怎么搞破坏。我做了这么多年安全,见过太多上线后才补漏洞的项目——那代价,啧啧,翻倍都是轻的。

这一章我们聚焦三个核心:STRIDE模型、数据流图(DFD)、以及威胁识别与风险评估。这三样东西串起来,就是一套完整的威胁建模流程。

为什么非做威胁建模不可?

你想想看,一个系统从设计到上线,中间有多少环节可能出问题?接口、存储、传输、认证……每个点都可能被利用。威胁建模就是把这些点提前找出来,在代码还没写之前就把坑填上。

我记得有一次,团队赶工期,跳过了威胁建模直接开干。结果上线第一天,用户A竟然能查到用户B的订单数据。原因?权限校验漏了一个接口。如果当时画了DFD,这个接口肯定会被标出来。

STRIDE模型:六类威胁,一个不漏

STRIDE是微软提出的威胁分类法,六个字母对应六类威胁。我习惯把它贴在显示器边上,每次做威胁建模都过一遍。

字母 威胁类型 核心问题 典型场景
S Spoofing(假冒) 谁能假装成别人? 伪造JWT Token、盗用Session
T Tampering(篡改) 数据能被非法修改吗? 中间人改请求参数、篡改配置文件
R Repudiation(抵赖) 做了坏事能赖账吗? 缺少操作日志、日志可被删除
I Information Disclosure(信息泄露) 敏感数据能被看到吗? 明文密码、API返回多余字段
D Denial of Service(拒绝服务) 系统能被搞瘫痪吗? 无频率限制、死循环调用
E Elevation of Privilege(权限提升) 普通用户能当管理员吗? 越权访问、SQL注入提权
我的习惯:每次评审设计文档,我都拿STRIDE当checklist逐条过。别嫌麻烦,漏掉一个可能就是一次安全事件。

数据流图(DFD):把系统画出来,威胁才看得见

DFD不是安全专属的工具,但用在威胁建模上特别好使。它把系统拆成几个基本元素:外部实体、过程、数据存储、数据流。画出来之后,威胁就藏不住了。

我见过有人直接对着代码做威胁建模,结果漏了一堆外部依赖。DFD强迫你把所有边界都画出来——第三方API、数据库、缓存、消息队列……一个都不能少。

DFD核心元素

  • 外部实体:用户、第三方系统、定时任务——画在边界外面
  • 过程:业务逻辑、API处理、数据转换——用圆圈表示
  • 数据存储:数据库、文件、缓存——用两条横线
  • 数据流:箭头表示数据走向——标清楚传输协议
注意:DFD只画数据流,不画控制流。我曾经看到有人把if-else都画进去,那就不叫DFD了,叫流程图。DFD关注的是“数据去了哪里”,不是“程序怎么执行”。

一个简单的DFD示例

下面是一个用户登录场景的DFD。我故意简化了,但核心结构都在。

用户登录场景 - 数据流图(DFD) 用户 登录 服务 用户DB 账号+密码 查询凭证 返回结果 Token/失败 信任边界
关键点:注意那条虚线——信任边界。用户在外面,登录服务和数据库在里面。跨过这条边界的每个数据流,都是潜在的威胁面。

威胁识别:把STRIDE套在DFD上

DFD画好了,STRIDE模型也记住了,接下来就是把两者结合起来。我习惯对DFD里的每个元素,逐个问STRIDE的六个问题。

举个例子,上面那个登录场景:

  • S - 假冒:用户能不能伪造别人的账号密码?登录服务会不会被假冒?
  • T - 篡改:账号密码在传输过程中能被改吗?数据库里的凭证能被改吗?
  • R - 抵赖:用户登录失败后能说“我没试过”吗?有没有日志?
  • I - 信息泄露:密码是明文传输的吗?数据库存的是明文吗?
  • D - 拒绝服务:登录接口能被暴力刷爆吗?数据库连接池够用吗?
  • E - 权限提升:登录成功后,用户能拿到管理员权限吗?
避坑指南:我曾经在一个支付系统里,只关注了“用户->支付服务”这条流,忽略了“支付服务->银行网关”这条外部流。结果银行网关的证书校验没做,差点出事。记住:每一条跨信任边界的数据流,都要过一遍STRIDE。

风险评估:不是所有威胁都要修

识别出威胁之后,下一步是评估风险。不是每个威胁都值得花大价钱去修。我常用的方法是DREAD模型,给每个威胁打分。

维度 说明 评分(1-10)
D - Damage Potential 如果被利用,损失多大? 数据泄露=10,服务降级=3
R - Reproducibility 攻击能复现吗? 每次都能=10,特定条件=3
E - Exploitability 攻击难度高吗? 工具一把梭=10,需要0day=2
A - Affected Users 影响多少用户? 全部=10,个别=2
D - Discoverability 漏洞容易被发现吗? 公开信息=10,需要内鬼=1

总分 = (D + R + E + A + D) / 5。我一般这样定优先级:

  • 8-10分:必须修,上线前解决
  • 5-7分:尽量修,可以加缓解措施
  • 1-4分:记录在案,后续迭代再处理
别掉进完美主义陷阱:我见过一个团队,花了两周去修一个评分只有2分的威胁——某个内部管理接口需要内网+特定IP才能访问,他们非要加双因子认证。有这个时间,不如去修那个评分9分的SQL注入。记住:安全是风险管理,不是消除所有风险。

威胁建模的整体流程

最后,我把整个流程串起来。你照着这个步骤走,基本不会漏。

  1. 画DFD:把系统拆成外部实体、过程、数据存储、数据流,标出信任边界
  2. 套STRIDE:对每个元素和每条数据流,逐类问“有没有威胁”
  3. 记录威胁:每个威胁写清楚:位置、类型、描述、影响
  4. 评估风险:用DREAD打分,排优先级
  5. 制定对策:高优先级的定方案,中优先级的加缓解,低优先级的记录
  6. 验证:上线前做安全测试,确认对策有效

嗯,这套流程我用了快十年,从Web应用到嵌入式系统,基本都能覆盖。你刚开始做的时候可能会觉得慢,但熟练之后,一个中等规模系统的威胁建模,半天就能搞定。