深入理解威胁建模:从STRIDE到数据流图

威胁建模听起来挺高大上的,说白了就是「先画图、再找茬」—— 把你SDK里所有数据流、处理过程、存储点都画出来,然后挨个问:「这里有没有可能被人搞?」。我自己做安全评估时,80%的高危漏洞都是在威胁建模阶段就发现了,等代码写完了再修,成本完全不同。

这一章,我带你走完威胁建模的完整闭环。三种核心工具:STRIDE模型、数据流图、威胁识别方法。

STRIDE模型:六类威胁一把抓

威胁类别 定义 SDK里的例子
Spoofing 假冒 攻击者冒充合法身份 伪造、模拟客户端证书
Tampering 篡改 数据在传输或存储中被修改 中间人改签数据包、本地缓存被篡改
Repudiation 抵赖 用户否认做过某操作 日志缺失、缺少签名机制
Information Disclosure 信息泄露 敏感数据被未授权获取 日志打印、硬编码密钥
Denial of Service 拒绝服务 资源被恶意消耗 无限制重试、大包攻击
Elevation of Privilege 权限提升 低权限用户获得高权限 SDK内部接口未做鉴权、提权利用

我记得第一次用STRIDE分析一个支付SDK时,把六个字母贴在白板上,一个节点一个节点过。刚开始觉得「这有什么好查的」,结果发现数据存储的加密只是伪加密,属于典型的Tampering + Information Disclosure双重威胁。嗯,从那以后我再也不敢小看这六个字母了。

数据流图:给SDK画张「解剖图」

数据流图(DFD)是威胁建模的基础素材。没有图,你的威胁分析就是瞎猜。我习惯把DFD分成四个要素来画:

  • 外部实体(圆角矩形):调用SDK的App、后端服务器、第三方服务
  • 处理过程(圆/椭圆):SDK内部的初始化、加密、网络发送等模块
  • 数据存储(开口矩形/平行线):本地数据库、SharedPreferences、文件缓存
  • 数据流(箭头):请求、响应、回调数据

核心原则:信任边界必须标出来。每次数据跨越信任边界,就是一次威胁检查点。

我见过不少团队画DFD时把数据存储画成「数据库」,忽略了配置文件、日志文件、内存缓存这类存储点。你想想看,日志里如果打了用户,那不就是信息泄露吗?

我的小技巧:第一次画DFD时别追求完美。先画一个全局大图,再逐层拆解。比如SDK启动流程一层、网络交互一层、持久化一层。分层到位后,威胁就藏不住了。

威胁识别:把STRIDE套在DFD上

图有了,模型有了,接下来就是实际干活了。我通常按照下面五步走:

  1. 拆解数据流:每一条箭头都不要放过。从入口到出口,中间停在哪,经过哪些处理。

  2. 对标STRIDE:每个DFD元素问一遍「这个节点能不能被S/T/R/I/D/E?」。比如数据存储能不能被篡改?外部实体能不能被假冒?

  3. 画威胁清单:写出来,别只靠脑子记。用表格,列清楚:威胁编号、威胁描述、影响元素、STRIDE分类。

  4. 初步分级:高、中、低三档。高风险立马处理,中风险排期,低风险放看板。

  5. 记录在案:每一次威胁建模都要存档。我见过项目上线了发现漏洞,结果查记录才发现在威胁建模阶段就识别过,但没人跟进。

千万注意:威胁识别不是一次性的。SDK迭代一次,DFD就要更新一次,威胁清单就要刷新一次。我曾经接手过一个SDK的第二版本,第一版的威胁建模文档还写着「无风险」——结果我一查,新加的推送模块直接暴露了设备ID。所以别偷懒,迭代必重做。

知识体系一图清

下面这张图展示了本章的完整逻辑:以数据流图为中心,用STRIDE模型逐元素扫描,最终形成威胁清单。我看着这张图做安全评估,基本不会漏东西。

威胁建模核心流程 数据流图 (DFD) S 假冒 T 篡改 R 抵赖 I 信息泄露 D 拒绝服务 E 权限提升 威胁 #1 威胁 #2 威胁 #3 威胁 #4 威胁 #5 逐元素检查,生成威胁清单

你可能会问:「这六类威胁里,哪些在SDK中最常见?」根据我的经验,信息泄露(I)和假冒(S)出现频率最高。原因很简单——SDK运行在宿主App的进程空间里,数据和密钥藏不住;同时SDK的经常被硬编码或容易被窃取。所以如果你时间有限,先把I和S扫一遍,通常能抓到80%的问题。

一句话总结本章:用DFD把SDK画出来,用STRIDE把每种威胁列出来,剩下的就是填表和修bug了。别想得太玄,威胁建模就是一个「先画再查」的结构化过程。