4、威胁建模:STRIDE模型、攻击树分析、资产识别与风险评级、数据流图绘制
威胁建模,说白了就是「先想清楚坏人会怎么搞我们,然后再动手防御」。很多团队一上来就写代码、跑扫描,结果上线后被一个早就该发现的逻辑漏洞打穿。我个人的习惯是:任何安全测试开始前,先花半天做威胁建模。这步省了,后面全是补窟窿。
4.1 资产识别与风险评级
做威胁建模的第一步,不是画图,不是列威胁,而是搞清楚——你到底要保护什么?
我在项目中遇到过好几次,团队花了两周做渗透测试,结果发现最核心的数据库根本没在测试范围内。为什么?因为没人把「数据资产清单」列出来。
资产识别三要素:
- 数据资产:用户密码、支付信息、业务密钥、日志记录
- 系统资产:API网关、数据库、缓存、消息队列
- 基础设施资产:云主机、容器、负载均衡、DNS
识别出来后,要做风险评级。我一般用这个简易矩阵:
| 等级 | 影响描述 | 示例 | 响应要求 |
|---|---|---|---|
| P0 | 数据泄露/服务瘫痪 | 用户密码明文存储 | 立即修复,阻断上线 |
| P1 | 功能绕过/权限提升 | 未授权访问管理接口 | 24小时内修复 |
| P2 | 信息泄露/配置缺陷 | 错误日志暴露堆栈 | 本周内修复 |
| P3 | 低风险/需持续监控 | 非关键接口缺少限流 | 下个迭代修复 |
我的经验:资产清单一定要让开发、运维、产品三方一起过一遍。我曾经见过运维说「这个数据库没数据」,结果里面存了三年的用户行为日志——嗯,那也算敏感资产。
4.2 数据流图绘制
数据流图(DFD)是威胁建模的「地图」。没有它,你根本不知道数据从哪来、到哪去、经过谁的手。
画DFD,我建议遵循这四步:
- 画外部实体:用户、第三方服务、管理员——这些是数据的起点和终点
- 画处理过程:登录模块、支付服务、订单引擎——数据在这里被加工
- 画数据存储:MySQL、Redis、文件系统——数据在这里休息
- 画数据流:用箭头把上面三者连起来,标注传输协议(HTTP/HTTPS/RPC)
下面是我画的一个简化版电商系统数据流图,你可以参考这个结构:
画图避坑:我曾经见过有人把DFD画成了网络拓扑图——交换机、路由器全画上去了。记住,DFD关注的是数据,不是设备。别把防火墙、负载均衡画成处理节点,它们只是通道。
4.3 STRIDE模型:六类威胁逐个拆解
STRIDE是微软提出的威胁分类模型,六个字母对应六类威胁。我每次做威胁建模,都会拿这个清单对着数据流图一个一个过。
| 字母 | 威胁类型 | 通俗理解 | 典型场景 |
|---|---|---|---|
| S | Spoofing(假冒) | 冒充别人身份 | 伪造JWT Token、会话劫持 |
| T | Tampering(篡改) | 数据被改 | 修改请求参数、篡改数据库 |
| R | Repudiation(抵赖) | 做了不承认 | 缺少审计日志、日志可被删除 |
| I | Information Disclosure(信息泄露) | 不该看的看到了 | 接口返回密码、错误堆栈暴露 |
| D | Denial of Service(拒绝服务) | 服务不可用 | 接口无限流、慢查询攻击 |
| E | Elevation of Privilege(权限提升) | 普通用户干管理员的事 | 水平越权、垂直越权 |
怎么用?举个例子。拿上面那张DFD图,看「用户→API网关→登录服务→用户DB」这条路径:
- S:用户能不能伪造别人的Token?——检查签名算法
- T:请求在传输中能不能被篡改?——必须用HTTPS
- R:登录失败有没有日志?——记录IP、时间、用户名
- I:登录接口返回的报错信息会不会泄露「用户不存在」?——统一返回「用户名或密码错误」
- D:登录接口有没有限流?——加验证码+频率限制
- E:普通用户能不能调用管理员的登录接口?——接口权限隔离
我的习惯:每一条数据流路径,都按STRIDE过一遍。刚开始可能觉得慢,但熟练后,一张DFD图半小时就能扫完。扫出来的威胁,直接记到风险清单里。
4.4 攻击树分析:把威胁变成攻击路径
STRIDE告诉你「有什么威胁」,攻击树告诉你「怎么实现这个威胁」。攻击树是一种树形结构,根节点是攻击目标,子节点是达成目标需要的步骤。
举个例子,攻击目标是「获取管理员权限」:
注意:攻击树不是画得越细越好。我见过有人把「打开电脑」都画成攻击步骤——没必要。攻击树的粒度,控制在能直接对应到防御措施就行。比如「SQL注入」对应「参数化查询」,「暴力破解」对应「限流+验证码」。
4.5 把威胁建模结果落地
画完图、列完威胁、建完攻击树,然后呢?很多人停在这里,觉得「模型做完了」。其实这才刚开始。
我一般会输出三样东西:
- 威胁清单:每个威胁对应STRIDE分类、影响等级、攻击路径
- 缓解措施表:每个威胁至少有一条缓解措施,标注责任人
- 测试用例:把威胁清单直接转成安全测试用例,交给测试团队
举个例子,威胁清单的格式:
| ID | 威胁描述 | STRIDE | 风险等级 | 缓解措施 | 测试用例 |
|---|---|---|---|---|---|
| T-001 | 登录接口无验证码,可暴力破解 | S | P1 | 增加图形验证码+5次失败锁定 | 连续尝试100次不同密码 |
| T-002 | 订单接口未校验用户ID,可越权查看他人订单 | E | P0 | 后端校验当前用户ID与订单所属用户ID一致 | 修改订单ID参数访问他人订单 |
| T-003 | 错误日志返回完整SQL语句,泄露数据库结构 | I | P2 | 生产环境关闭详细错误信息 | 触发SQL错误,检查返回内容 |
我的经验:威胁建模不是一次性的。每次迭代、每次架构变更,都要重新过一遍。我见过一个项目,半年没更新威胁模型,结果新加的文件上传功能直接被拿下了服务器——嗯,因为威胁模型里根本没画这个新模块。