4. 威胁建模实战

面试中一旦被问到“给你一个Web系统,现场做一次威胁建模”,很多候选人会立刻背出STRIDE六个字母,然后陷入沉默。面试官真正想看的不是定义复述,而是你能否在有限时间内,把一套方法论落到具体系统上,产出可执行的缓解措施。本节以一个真实的电商订单查询系统为对象,完整走一遍从建模到输出的过程。

先明确建模对象与边界

假设系统是一个面向外部用户的订单查询服务,典型架构为:浏览器 → CDN/WAF → Nginx反向代理 → 订单查询微服务(Java)→ MySQL主库/只读副本,同时微服务会调用用户中心(校验身份)和缓存(Redis)。数据流上,用户提交订单号与登录态,服务端校验后返回订单详情,包含收货地址、手机号、支付金额等敏感字段。

建模第一步不是套框架,而是画数据流图(DFD)并标注信任边界。信任边界至少有三条:互联网与DMZ之间、DMZ与应用内网之间、应用与数据层之间。每条边界都是威胁高发区,后续分析要围绕它们展开。这一步在面试中要口头说清楚,因为它决定了后面威胁是否“找得全”。

用STRIDE做系统性威胁枚举

STRIDE的价值在于“不遗漏类别”。针对上面的DFD,逐元素过一遍:

STRIDE类别对应安全属性本系统具体威胁示例
Spoofing 仿冒认证攻击者伪造他人登录态或重放token查询他人订单
Tampering 篡改完整性篡改请求中的orderId越权访问;篡改返回数据
Repudiation 抵赖不可否认查询敏感订单无审计日志,无法追溯谁查过
Information Disclosure 信息泄露机密性越权IDOR导致订单、手机号、地址泄露;日志打印明文
Denial of Service 拒绝服务可用性高频查询打满数据库连接;复杂查询拖垮服务
Elevation of Privilege 权限提升授权普通用户通过参数构造访问管理接口或他人订单

注意,STRIDE是“枚举工具”,不是“排序工具”。它帮你把威胁列全,但哪个先修、哪个风险高,需要DREAD来辅助判断。

用DREAD给威胁排优先级

DREAD从五个维度打分(1-10分),取平均或加权。以“越权查询他人订单(IDOR)”为例,给出一个可复现的打分示例(以下为教学假设值,非实测):

威胁:通过修改orderId越权查询他人订单
D 潜在损害(Damage)        = 9   (泄露手机号、地址、金额)
R 可复现性(Reproducibility)= 10  (改一个数字即可,稳定复现)
E 可利用性(Exploitability) = 8   (无需高深技术,工具即可)
A 受影响用户(Affected)     = 9   (所有下单用户)
D 可发现性(Discoverability)= 7   (orderId规律性强,易枚举)

DREAD得分 = (9+10+8+9+7)/5 = 8.6  → 高风险,优先修复

对比另一个威胁“日志中打印明文手机号”,其可复现性和可利用性较低(需要拿到日志权限),DREAD可能只有5分左右,优先级自然靠后。面试中要强调:DREAD是主观打分,团队需统一标尺,否则分数没有可比性。它的作用是排序,不是精确度量。

用PASTA补上“攻击者视角”

STRIDE偏系统视角,PASTA(攻击模拟与威胁分析流程)则从攻击者动机出发,分七阶段。实战中不必全走完,重点用它的“攻击者中心”思路。针对本系统,可以问三个问题:攻击者是谁?动机是什么?最可能走哪条路径?

例如,黑产攻击者的动机是批量获取用户手机号用于营销或诈骗。其最可能路径是:注册普通账号 → 抓包发现orderId为自增数字 → 编写脚本遍历 → 批量拉取订单。这条路径直接指向“越权+可枚举”两个根因。PASTA的产出不是威胁清单,而是“攻击场景”,它让缓解措施更有针对性——比如把orderId改为不可枚举的UUID,并强制服务端校验订单归属。

用攻击树把单点威胁展开成路径

攻击树适合把一个高层目标拆成可操作的子步骤。以“获取他人订单信息”为根节点:

目标:获取他人订单信息
├── 路径A:越权访问
│   ├── A1 枚举orderId(自增/规律)
│   ├── A2 绕过归属校验(服务端未校验userId)
│   └── A3 利用管理接口未鉴权
├── 路径B:窃取凭证
│   ├── B1 XSS窃取token
│   └── B2 中间人截获(未强制HTTPS)
└── 路径C:数据库直连
    ├── C1 SQL注入
    └── C2 配置泄露导致直连

攻击树的叶子节点就是具体攻击手法,每个叶子都可以对应一条缓解措施。这种结构在面试中非常加分,因为它展示了“从目标反推防御”的思维,而不是零散地罗列威胁。

输出缓解措施:从威胁到可执行动作

建模的终点是缓解措施。措施必须具体到“改什么、怎么改、怎么验证”,而不是“加强鉴权”这种空话。以下是一份可直接参考的缓解措施表(示例):

威胁缓解措施验证方式
越权查询(IDOR)服务端每次查询强制校验order.userId == 当前登录userId;orderId改为UUID用A账号token查B账号订单,返回403;抓包确认orderId非自增
token重放token绑定设备指纹+短有效期+一次性nonce重放同一请求,第二次返回401
敏感信息泄露返回字段最小化,手机号脱敏;日志禁止打印明文检查响应体与日志文件,确认无完整手机号
高频查询DoS按用户+IP限流;查询走只读副本;复杂查询加超时压测单用户高频请求,观察是否触发429
SQL注入全部使用参数化查询;WAF规则兜底用sqlmap对查询接口扫描,确认无注入点

注意最后两列:缓解措施必须可验证。面试官常追问“你怎么知道修好了”,能答出验证方式,说明你真的做过,而不是纸上谈兵。

现场建模的时间分配建议

面试通常只有20-30分钟。建议:5分钟画DFD和信任边界,8分钟用STRIDE枚举,5分钟用DREAD排序,5分钟用攻击树展开最高风险项,最后5分钟输出缓解措施。PASTA可作为思路融入,不必单独走七阶段。关键是让面试官看到你有结构、有取舍、有落地。

最后提醒一点:威胁建模不是一次性活动。系统迭代、新接口上线、架构调整后都要重新过一遍。面试中如果能主动提到“建模要纳入DevSecOps流程,在需求评审阶段就介入”,会显著提升专业度。