数据流图绘制:DFD 的要素、绘制方法与威胁建模应用
数据流图,简称 DFD,是威胁建模里最基础也最核心的工具。说白了,它就是一张“系统怎么动起来”的蓝图。我刚开始做安全设计时,总觉得画图浪费时间,直接上手写代码多痛快。结果呢?后来做威胁分析,发现漏了一堆边界和交互点,补起来比画十张图还累。
今天咱们就聊聊 DFD 的三个核心问题:它由什么组成?怎么画?画完怎么用在威胁建模里?
DFD 的四大要素
DFD 的符号其实不多,就四种。但每一种都对应着威胁建模里的关键角色。
| 要素 | 符号形状 | 威胁建模中的含义 | 我见过的坑 |
|---|---|---|---|
| 外部实体 | 矩形 | 数据来源或终点,通常是用户、第三方系统 | 有人把数据库也画成外部实体,其实它是数据存储 |
| 过程 | 圆形/圆角矩形 | 数据处理单元,比如认证模块、支付服务 | 过程太粗,一个圆里塞了十件事,分析时根本看不清 |
| 数据存储 | 开口矩形(两条横线) | 数据停留的地方,数据库、文件、缓存 | 漏掉日志存储,结果日志泄露成了大漏洞 |
| 数据流 | 带箭头实线 | 数据在实体、过程、存储之间的移动 | 箭头方向画反,威胁分析全错位 |
如何绘制 DFD:三步法
画 DFD 不是一蹴而就的。我一般分三步走,从粗到细,逐步展开。
第一步:画上下文图(Level 0)
上下文图是整个系统的“全景图”。只有一个过程节点,代表整个系统。外部实体和系统之间的数据流,就是系统的边界。
举个例子,一个简单的登录系统:
- 外部实体:用户
- 过程:登录系统
- 数据流:用户发送“用户名+密码”,系统返回“登录结果”
这一步的关键是:明确信任边界。系统内部的东西,全藏在那个圆里。外部实体和系统之间的交互,就是威胁建模的起点。
第二步:分解为 Level 1 图
把上下文图里的那个圆拆开,露出里面的过程、数据存储和数据流。这一步要遵循一个原则:每个过程只做一件事。
还是登录系统的例子,Level 1 图可能包含:
- 过程:用户输入验证、密码哈希比对、会话生成
- 数据存储:用户凭证库、会话缓存
- 数据流:验证请求、哈希结果、会话令牌
你想想看,如果我把“用户输入验证”和“密码哈希比对”画成一个过程,那后面做威胁分析时,就分不清是输入校验出了问题,还是哈希算法出了问题。拆得越细,分析越准。
第三步:按需继续分解(Level 2+)
对于复杂模块,可以继续分解到 Level 2 甚至 Level 3。但别贪多。我个人的经验是:分解到每个过程能对应一个代码模块或一个微服务为止。再往下画,就变成代码流程图了,那是开发的事。
DFD 在威胁建模中的应用
DFD 画完,不是用来挂墙上的。它是威胁建模的“作战地图”。
1. 识别信任边界
DFD 里的每个过程、数据存储、外部实体,都有其所属的信任域。数据流跨越信任边界的地方,就是威胁的高发区。
举个例子,用户浏览器(外部实体)到 Web 服务器(过程)之间,是互联网边界。这里需要 HTTPS、输入校验、防 CSRF。而 Web 服务器到数据库(数据存储)之间,是内部网络边界。这里需要 SQL 注入防护、最小权限。
2. 应用 STRIDE 模型
STRIDE 是微软提出的威胁分类模型,每个字母代表一种威胁类型。把 DFD 的每个元素和 STRIDE 对照,就能系统性地发现威胁。
| DFD 元素 | STRIDE 威胁 | 典型问题 |
|---|---|---|
| 外部实体 | 欺骗 (S) | 身份伪造、重放攻击 |
| 过程 | 篡改 (T)、拒绝服务 (D) | 代码注入、资源耗尽 |
| 数据存储 | 信息泄露 (I)、篡改 (T) | 数据泄露、未授权修改 |
| 数据流 | 信息泄露 (I)、篡改 (T) | 中间人攻击、数据窃听 |
3. 生成威胁清单
把 DFD 上标注的威胁整理成清单,就是安全需求的输入。每个威胁对应一个或多个缓解措施。
比如:
- 威胁:数据流“用户凭证”可能被窃听 → 缓解:使用 TLS 加密
- 威胁:过程“密码哈希比对”可能被篡改 → 缓解:代码签名、运行时完整性校验
- 威胁:数据存储“用户凭证库”可能泄露 → 缓解:加密存储、访问控制
你看,威胁清单不是凭空想出来的,而是从 DFD 上一步步推导出来的。这就是“数据流图驱动威胁建模”的核心思想。
一张图总结 DFD 与威胁建模的关系
下面这张 SVG 图,展示了 DFD 如何与威胁建模流程衔接。我习惯把它贴在团队的白板上,每次评审时都过一遍。
避坑指南:画 DFD 时常见的五个错误
这些年我评审过不少团队的 DFD,发现几个反复出现的问题。列出来,大家画图时对照一下。
- 过程太粗:一个圆里塞了“用户管理”、“订单处理”、“支付结算”。这种图没法做威胁分析。拆!
- 数据流没标注内容:光画箭头,不写传什么数据。后面分析时,根本不知道哪些是敏感数据。
- 漏掉数据存储:尤其是日志、缓存、临时文件这些“隐形”存储。我曾经见过一个系统,日志里存了明文密码,但 DFD 上根本没画日志存储。
- 信任边界画错:把内部网络和外部网络混在一起。记住:每一条跨越信任边界的数据流,都是威胁建模的重点。
- 只画 Level 0,不往下分解:上下文图只能看到系统边界,看不到内部威胁。至少分解到 Level 1。
好了,DFD 的核心内容就这些。记住:DFD 不是画给领导看的,是画给自己做威胁分析用的。画得越认真,后面的安全需求就越扎实。