威胁建模入门:从“拍脑袋”到“有章法”
很多安全新人问我:“老哥,做安全分析到底从哪下手?”
我的回答永远是——先做威胁建模。说白了,就是在攻击者动手之前,你先替他把路走一遍。我早年做渗透测试时,经常遇到一种情况:客户说系统很安全,结果我随便翻翻数据流图,就发现三四个高危点。嗯,那时候我就意识到,没有威胁建模的安全分析,基本等于盲人摸象。
什么是威胁建模?
威胁建模不是画几张图就完事。它是一种结构化的分析方法,用来识别、评估和缓解系统面临的安全威胁。我个人习惯把它比作“安全领域的沙盘推演”——你站在攻击者的角度,把系统拆开揉碎,看看哪里可能出问题。
核心三问:
- 系统里有什么?(资产、组件、数据流)
- 谁可能攻击它?(攻击者画像、动机)
- 怎么攻击它?(攻击路径、威胁类型)
我在项目中遇到过最典型的反面教材:一个金融支付团队,上线前只做了功能测试,结果上线第一天就被撞库攻击打穿。后来我帮他们做威胁建模,发现数据流图里密码校验环节居然没有限流——这种问题,建模阶段就能发现。
STRIDE模型详解
STRIDE是微软提出的威胁分类模型,也是我这些年用得最顺手的工具。它把威胁分成六类,每类对应一个安全属性。你想想看,这就像给系统做体检,每个科室查不同的病。
| 威胁类型 | 英文 | 对应安全属性 | 通俗理解 |
|---|---|---|---|
| S - 欺骗 | Spoofing | 身份认证 | 冒充别人身份干坏事 |
| T - 篡改 | Tampering | 完整性 | 数据或代码被偷偷改了 |
| R - 抵赖 | Repudiation | 不可否认性 | 干了事不认账 |
| I - 信息泄露 | Information Disclosure | 机密性 | 不该看的人看到了 |
| D - 拒绝服务 | Denial of Service | 可用性 | 让系统瘫掉,谁也别用 |
| E - 权限提升 | Elevation of Privilege | 授权 | 普通用户拿到管理员权限 |
我的小技巧:每次做威胁建模,我都会把STRIDE六类列在便签纸上,对着数据流图一个一个过。这样不容易漏项。我曾经因为漏了“抵赖”这一项,导致一个日志审计系统上线后,攻击者删了日志就跑,根本追溯不到——从那以后,我再也不敢跳过任何一类。
数据流图绘制基础
数据流图(DFD)是威胁建模的“地图”。没有它,你根本不知道数据从哪来、到哪去、经过谁的手。我见过太多人一上来就画架构图,结果画完发现全是方框和箭头,根本看不出安全边界在哪。
绘制DFD,记住四个核心元素:
- 外部实体(矩形):系统外的人或系统,比如用户、第三方API
- 过程(圆形/椭圆):处理数据的动作,比如登录校验、数据加密
- 数据存储(双横线):存放数据的地方,比如数据库、缓存
- 数据流(箭头):数据移动的方向,比如HTTP请求、数据库查询
避坑指南:我曾经见过一个团队画的DFD,把整个系统画成一个圆,外面画了一堆箭头——这等于没画。记住,DFD要分层,从顶层上下文图开始,逐层细化。别想一步到位,先画大框架,再往里填细节。
下面这张图是我常用的威胁建模流程,你可以把它当作操作手册:
实战:画一个登录模块的DFD
光说不练假把式。咱们拿一个最简单的登录模块来走一遍流程。
第一步:识别外部实体
- 用户(浏览器)
- 第三方OAuth服务(比如微信登录)
第二步:识别过程
- 登录校验(验证用户名密码)
- Token生成(签发JWT)
- 会话管理(维护登录状态)
第三步:识别数据存储
- 用户数据库(存密码哈希)
- 会话缓存(Redis)
第四步:画数据流
- 用户 → 登录校验:提交用户名+密码
- 登录校验 → 用户数据库:查询用户信息
- 登录校验 → Token生成:验证通过后请求签发Token
- Token生成 → 用户:返回JWT
- 用户 → 会话管理:携带Token访问受保护资源
威胁分析(用STRIDE过一遍):
- Spoofing:攻击者可能伪造Token或冒充第三方OAuth服务
- Tampering:密码在传输过程中可能被篡改(没上HTTPS的话)
- Repudiation:用户登录成功后没有日志,无法追溯
- Information Disclosure:密码明文传输,或者数据库密码没哈希
- Denial of Service:登录接口没限流,攻击者可以暴力破解
- Elevation of Privilege:普通用户通过修改Token payload提权
我的经验:每次做完威胁分析,我都会把结果整理成一张表,标注威胁等级和缓解措施。这样开发团队拿到手就能直接干活。别光列问题,不给解法——那是耍流氓。
好了,威胁建模入门就聊到这儿。记住,STRIDE是工具,DFD是地图,真正的功夫在于你能不能把这两样东西用起来,在系统还没上线之前就把坑填上。下次你拿到一个新系统,别急着写代码,先画张DFD,过一遍STRIDE——你会发现,很多问题其实早就写在纸上了。