3. STRIDE模型详解(上):Spoofing(欺骗)与Tampering(篡改)的实战案例分析
好,咱们正式开始啃STRIDE这块硬骨头。很多新手看到这六个字母就头大,觉得是理论派搞出来的花架子。其实不然,STRIDE是我个人最常用的威胁建模工具,没有之一。它就像一把瑞士军刀,每个刀片都能解决一类特定的安全问题。
今天我们先聊前两个:Spoofing(欺骗)和Tampering(篡改)。这两个家伙经常一起出现,但本质完全不同。你想想看,一个是要装成别人混进来,另一个是偷偷改你东西。嗯,咱们一个一个拆解。
3.1 Spoofing(欺骗):谁在敲门?
Spoofing说白了就是身份伪装。攻击者假装成某个合法用户、系统或组件,来获取不该有的权限。我在项目中遇到过最典型的案例:一个内部管理系统,登录页面只校验了用户名和密码,但完全没有做任何来源校验。结果有人用抓包工具改了HTTP请求里的用户ID字段,直接冒充管理员进了后台。
为什么会这样?因为系统只相信了“声称的身份”,而没有验证“真实的身份”。
3.1.1 欺骗的常见场景
- 用户身份欺骗:盗用账号、会话劫持、重放攻击
- IP地址欺骗:伪造源IP绕过白名单
- DNS欺骗:把域名解析指向恶意服务器
- 进程/服务欺骗:恶意进程伪装成系统服务
核心判断标准:如果威胁涉及“冒充他人/他物获取信任”,那就是Spoofing。
3.1.2 实战案例:一个简单的登录系统
假设我们有一个Web应用,用户登录后服务端返回一个Session ID。代码大概长这样:
// 伪代码 - 有问题的实现
app.post('/login', (req, res) => {
const { username, password } = req.body;
const user = db.findUser(username, password);
if (user) {
// 直接使用用户名作为身份标识
res.cookie('session', username);
res.send('登录成功');
}
});
看出问题了吗?Session的值直接就是用户名,没有任何签名或加密。攻击者只要在浏览器里改一下Cookie,就能变成任何人。
我的建议:永远不要用可预测或可篡改的值作为身份凭证。Session ID必须使用加密安全的随机数生成器,并且要签名防篡改。
3.1.3 如何防御Spoofing
| 防御手段 | 说明 | 我踩过的坑 |
|---|---|---|
| 强认证机制 | 多因素认证、OAuth、证书 | 曾经只做了密码校验,结果被撞库攻破 |
| 会话管理 | 随机Token、HttpOnly Cookie、定期轮换 | 忘了设置过期时间,Session长期有效 |
| 来源验证 | 校验Referer、Origin头、客户端证书 | CSRF攻击就是因为没校验来源 |
| 消息认证 | 数字签名、MAC码 | API接口没做签名,被重放攻击打穿 |
避坑指南:我曾经在一个项目中,为了“用户体验”把Session有效期设成了30天。结果一个员工的电脑被同事借用,所有系统都被逛了个遍。记住:便利性和安全性永远是跷跷板。
3.2 Tampering(篡改):数据被动了手脚
Tampering关注的是数据完整性。攻击者虽然没有冒充别人,但他修改了传输中或存储中的数据。说白了,就是有人在你眼皮底下改了东西,而系统浑然不知。
我记得有一次做渗透测试,发现一个电商网站的价格参数直接放在URL里:?productId=123&price=99.00。我随手改成price=0.01,结果真的以一分钱下了单。这就是典型的Tampering攻击。
3.2.1 篡改的常见场景
- 网络传输篡改:中间人攻击修改HTTP请求/响应
- 参数篡改:修改URL参数、表单隐藏字段、Cookie值
- 文件篡改:替换配置文件、DLL劫持、固件篡改
- 数据库篡改:SQL注入修改数据
核心判断标准:如果威胁涉及“未经授权修改数据或代码”,那就是Tampering。
3.2.2 实战案例:API接口的数据完整性
来看一个常见的API设计:
// 伪代码 - 有问题的API
app.post('/transfer', (req, res) => {
const { fromAccount, toAccount, amount } = req.body;
// 直接信任客户端传来的数据
db.execute('UPDATE accounts SET balance = balance - ? WHERE id = ?',
[amount, fromAccount]);
db.execute('UPDATE accounts SET balance = balance + ? WHERE id = ?',
[amount, toAccount]);
res.send('转账成功');
});
这个接口有三个问题:
- 没有校验fromAccount是否属于当前登录用户
- amount没有做范围校验(负数?超大数?)
- 没有做防篡改签名
攻击者只要抓包改一下amount的值,就能转走任意金额。更狠的,把amount改成负数,还能从别人账户里“吸”钱进来。
我的经验:所有从客户端传来的数据,都必须视为不可信的。哪怕是你自己前端生成的加密数据,也要在后端重新校验一遍。我曾经见过一个团队,前端做了加密,后端就直接信任了——结果攻击者直接调API绕过了前端。
3.2.3 如何防御Tampering
| 防御手段 | 说明 | 实战要点 |
|---|---|---|
| 数据签名 | HMAC、数字签名验证完整性 | 密钥要妥善保管,定期轮换 |
| 传输加密 | TLS/HTTPS防止中间人篡改 | 别忘了证书校验,别用自签名证书 |
| 输入校验 | 白名单校验、类型检查、范围限制 | 后端校验不能依赖前端 |
| 完整性校验 | 哈希校验、文件校验和 | 下载文件时一定要校验哈希值 |
| 最小权限 | 每个操作只给必要的数据访问权限 | 用户不能修改不属于自己的数据 |
避坑指南:我曾经接手过一个遗留系统,所有API参数都放在URL里,而且没有签名。当时为了快速修复,我建议先加HTTPS。结果HTTPS部署后,攻击者改用客户端代理工具,照样能改参数。记住:HTTPS只防中间人,不防客户端篡改。真正的解决方案是服务端签名校验。
3.3 Spoofing vs Tampering:怎么区分?
很多新手会搞混这两个。我教你一个简单的判断方法:
- Spoofing:问“你是谁?”——身份问题
- Tampering:问“数据对吗?”——完整性问题
举个例子:攻击者伪造了一个管理员账号登录系统,这是Spoofing。攻击者登录后修改了数据库里的工资数据,这是Tampering。前者是进门时骗过了门卫,后者是进门后改了文件。
一句话总结:Spoofing是“装成别人”,Tampering是“改你东西”。两者经常组合使用,但威胁建模时要分开分析。
3.4 实战练习:给你的系统做个体检
现在你可以拿自己的系统试试手。找三个功能点,分别问自己:
- 这个功能有没有身份验证?验证够不够强?
- 数据在传输和存储过程中,有没有被篡改的风险?
- 如果攻击者同时使用Spoofing和Tampering,会有什么后果?
我个人的习惯是,每做一个新功能,先画一个简单的数据流图,然后在每个数据流和存储点上标注Spoofing和Tampering的风险。这样代码还没写,坑就已经填了一半。
下一节我们会聊剩下的四个威胁:Repudiation(抵赖)、Information Disclosure(信息泄露)、Denial of Service(拒绝服务)和Elevation of Privilege(权限提升)。到时候你会发现,STRIDE这六个字母,每一个都能对应到真实世界里的血泪教训。
嗯,今天就到这里。记住:威胁建模不是纸上谈兵,而是让你在攻击者动手之前,先替他们想好所有坏主意。