威胁建模入门:STRIDE模型、数据流图、威胁识别

说实话,很多团队的SDK安全评估,都是从“拍脑袋”开始的。什么风险高?不知道。攻击者会怎么搞?没概念。最后只能对着OWASP Top 10一个个硬对,效果嘛……你懂的。

我个人习惯,上手先做威胁建模。说白了,就是站在攻击者的角度,把系统的里里外外过一遍。今天这章,咱们就聊聊怎么快速入门威胁建模,用上STRIDE模型和数据流图这套组合拳。

1. STRIDE模型——给威胁分个类

STRIDE是微软提出的威胁分类方法。六个字母,六类威胁。我刚开始学的时候,觉得这东西太理论,直到有一次做支付SDK评估……嗯,回头再说这个故事。

威胁类型 英文 核心问题 典型的SDK场景
S - 身份欺骗 Spoofing 攻击者能冒充别人吗? 被硬编码、模拟合法App调用SDK
T - 篡改 Tampering 数据或代码能被非法修改吗? 中间人修改SDK请求包、篡改本地配置文件
R - 抵赖 Repudiation 操作能追溯到具体用户吗? SDK日志不完整、缺少审计链路
I - 信息泄露 Information Disclosure 敏感数据会被不该看到的人看到吗? 明文传输、日志打印用户隐私
D - 拒绝服务 Denial of Service 系统资源会被耗尽吗? SDK大量请求API、崩溃导致App不可用
E - 权限提升 Elevation of Privilege 普通用户能得到管理员权限吗? SDK接口越权调用、恶意插件提权

这张表我建议贴在你工位上。每次评估一个新SDK,先把六类威胁过一遍,至少不会漏掉大头。

2. 数据流图——把系统画出来

光有分类还不够。你得知道系统里数据是怎么跑的。数据流图(DFD)就是干这个的。它不复杂,四个核心元素:外部实体、过程、数据存储、数据流。

我早期犯过一个错,画DFD只画正常流程,结果风险全藏在异常分支里。记住,攻击者从不走“常规路径”。

画图小技巧:从外向内画。先标出所有外部实体(用户、第三方服务、管理员),再画它们和系统之间的数据流,最后补内部过程和数据存储。

举个例子,一个简单的登录SDK,数据流图可能是这样的:

  • 外部实体:App客户端、后端认证服务
  • 过程:SDK登录模块、校验模块
  • 数据存储:本地缓存、用户信息数据库
  • 数据流:用户名密码 → SDK登录模块 → 后端认证服务 → 返回 → 存入本地缓存

有了这个图,你再套STRIDE,威胁点就非常清晰了。比如“用户名密码 → SDK登录模块”这段,是不是可能被中间人篡改?

3. 威胁识别——STRIDE × DFD 交叉分析

组合拳来了。把数据流图里的每个元素,都对着STRIDE问一遍。我个人习惯用一张矩阵表来做这件事。

DFD元素 S T R I D E 识别出的威胁
外部实体 - 客户端 ✔ ✔ ✔ 伪造App身份调用、抵赖请求、DDoS攻击
过程 - 登录模块 ✔ ✔ ✔ 暴力破解、日志泄露密钥、提权越权
数据存储 - 本地缓存 ✔ ✔ 篡改缓存数据、敏感被读取
数据流 - 网络通信 ✔ ✔ ✔ 中间人篡改、抓包泄露、缺少签名验证

做完这个矩阵,答案基本浮出水面。剩下的事就是把这些威胁记下来,排优先级,挨个处理。

4. 实操示例——一个真实的日志SDK评估

我记得有一次评估某个第三方日志SDK。当时画完DFD,发现日志数据流从App → SDK → 本地文件 → 定时上传到云端。用STRIDE一套……

  • Spoofing:没有鉴权,谁都能往云端传日志
  • Tampering:本地文件任何人都能读写
  • Information Disclosure:日志里包含了用户手机号……明文
  • Denial of Service:SDK上传占满带宽,导致App卡死

你看,四个问题全中。如果当时没有做威胁建模,直接上代码审计,可能就漏掉了最严重的隐私泄露问题。

# 一个简单的威胁建模辅助脚本(Python)
# 用于快速生成STRIDE分类标签

def classify_threat(dfd_element):
    """
    给定一个DFD元素名称,返回可能存在的STRIDE威胁列表。
    这只是一个示范,真实场景需要结合业务逻辑。
    """
    threats = []
    element_lower = dfd_element.lower()
    
    if "外部实体" in element_lower or "客户端" in element_lower:
        threats.extend(["Spoofing", "Repudiation", "Denial of Service"])
    if "过程" in element_lower or "模块" in element_lower:
        threats.extend(["Tampering", "Information Disclosure", "Elevation of Privilege"])
    if "数据存储" in element_lower:
        threats.extend(["Tampering", "Information Disclosure"])
    if "数据流" in element_lower or "网络" in element_lower:
        threats.extend(["Tampering", "Repudiation", "Information Disclosure"])
    
    return threats

# 示例
element = "外部实体 - App客户端"
print(classify_threat(element))  
# 输出: ['Spoofing', 'Repudiation', 'Denial of Service']
注意:自动分类只能辅助思考,不能替代人工分析。我在项目里遇到过工具漏报的情况,最终是靠手动走查才发现的。工具是辅助,脑子才是核心。

5. 把威胁建模变成习惯

说实话,威胁建模这件事,第一次会有点迷茫。画图不知道从哪画,分类不知道标哪类。但只要坚持用在3-5个项目里,你会发现它就像肌肉记忆一样自然。

我个人建议的落地步骤:

  1. 拿到SDK,先画一张数据流图,哪怕手画都行
  2. 对照STRIDE六类威胁,逐一问“这里有没有可能?”
  3. 把识别出的威胁记录成列表,附上可能的攻击路径
  4. 排优先级:哪些必须修、哪些可以接受

你想想看,和拍脑袋评估相比,这套流程是不是硬多了?

核心掌握:

  • STRIDE六类威胁:Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, Elevation of Privilege
  • 数据流图四元素:外部实体、过程、数据存储、数据流
  • 威胁识别 = STRIDE × DFD 组合矩阵
  • 工具辅助分析,但最终判断靠经验和业务理解
威胁建模核心流程结构图 系统资产 / SDK 1. STRIDE分类 S - 身份欺骗 T - 篡改 R - 抵赖 I - 信息泄露 D - 拒绝服务 E - 权限提升 2. 数据流图(DFD) 外部实体 过程 数据存储 数据流 3. 威胁识别:STRIDE × DFD 交叉分析 输出:风险列表 + 攻击路径 + 缓解措施 💡 核心思路 - 从系统资产出发 - 分别用STRIDE和DFD建模 - 交叉分析找出威胁点

这章的SVG图展示了威胁建模的整体骨架。从系统资产出发,左边走STRIDE分类,右边走数据流图,最后在底部汇合做交叉分析。你可以在做自己的评估时,把这个框架贴在旁边当checklist用。