威胁建模入门: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个项目里,你会发现它就像肌肉记忆一样自然。
我个人建议的落地步骤:
- 拿到SDK,先画一张数据流图,哪怕手画都行
- 对照STRIDE六类威胁,逐一问“这里有没有可能?”
- 把识别出的威胁记录成列表,附上可能的攻击路径
- 排优先级:哪些必须修、哪些可以接受
你想想看,和拍脑袋评估相比,这套流程是不是硬多了?
核心掌握:
- STRIDE六类威胁:Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, Elevation of Privilege
- 数据流图四元素:外部实体、过程、数据存储、数据流
- 威胁识别 = STRIDE × DFD 组合矩阵
- 工具辅助分析,但最终判断靠经验和业务理解
这章的SVG图展示了威胁建模的整体骨架。从系统资产出发,左边走STRIDE分类,右边走数据流图,最后在底部汇合做交叉分析。你可以在做自己的评估时,把这个框架贴在旁边当checklist用。