各位开发者大家好!今天,我想和大家聊聊一种在Web应用程序中非常常见,但一旦被利用就可能失控的安全漏洞及其解决方案。👨💻
想象一下,您最近在代码审查中发现了以下修改。
// 修改前 (Before) 👎
// const { userId } = req.params;
// 修改后 (After) 👍
const { userId } = req.session;
仅仅一行代码的改变。然而,这个微小的差异可能会将您的服务从地狱中拯救出来。如果您想对“为什么这更安全?”这个问题获得清晰的答案,请务必关注本文直到最后!🚀

🤔 问题的开始:从URL获取用户ID?
首先,我们来看看有问题的现有代码。
// 不安全的方式
const {
userId
} = req.params;
allocationsDAO.getByUserIdAndThreshold(userId, threshold, (err, allocations) => {
// ... 根据用户ID查询数据并显示结果
});
这段代码直接从URL路径中包含的值(req.params)获取并使用userId。例如,如果用户访问
乍一看似乎没什么问题,对吧?但这里隐藏着一个非常可怕的陷阱。
假设我是一个恶意用户“hacker”,我的ID是“user456”。我可能会访问
“咦?如果我只更改URL末尾的ID,是不是也能看到别人的信息?”
于是,我在地址栏中输入
这正是OWASP Top 10中常见的不安全直接对象引用(Insecure Direct Object Reference, IDOR)漏洞。这就像只要知道公寓的楼号和房间号,就可以随意打开别人家门进入一样。
✨ 完美的解决方案:可信信息存在于“会话”中!
那么,提供的修改后的代码是如何解决这个问题的呢?
// 修复 A4 不安全直接对象引用 - 从会话而不是URL参数中获取用户ID
const { userId } = req.session;
allocationsDAO.getByUserIdAndThreshold(userId, threshold, (err, allocations) => {
// ... 根据用户ID查询数据并显示结果
});
答案就是使用 req.session!
- req.params (URL参数): 这是用户可以在浏览器地址栏中随意操纵的值。它是一个绝不能信任的外部输入值。
- req.session (会话): 这是用户成功登录时,服务器内部存储并保证的信息,表明“该用户是经过认证的OOO”。用户无法直接修改此会话信息。它就像政府颁发的不可伪造的身份证。
新代码不关心URL中写了什么。相反,它从服务器上存储的当前登录用户的会话信息中获取userId。
因此,即使我以“user456”身份登录,并巧妙地将URL更改为…/allocations/user123并发送请求,服务器也会这样操作。
- “哦,用户‘user456’发送了一个请求。”(通过Cookie检查会话)
- “代码指示使用req.session.userId,所以我应该将‘user456’分配给userId变量。”
- “最终,我应该查询并显示‘user456’的数据。”
最终,我将永远无法看到他人的信息,只能查看我自己的信息。IDOR漏洞得到了完美的防御!🛡️
🎯 结论:您的代码安全吗?
今天我们讨论的代码更改的答案是明确的。
是的,将代码修改为从会话(req.session)而不是URL参数(req.params)中获取用户标识符,是大幅增强安全性的一个非常正确且重要的措施。👍
这个小小的改变是正确实现用户数据访问授权的关键一步。请始终记住:“所有来自用户的输入都是潜在的威胁。”尤其是在验证用户身份和控制权限时,绝不能相信用户可以操纵的值,而应使用服务器控制的可信信息(会话)。
现在就检查您的代码。您是否在查询重要数据时直接使用了URL中的值呢?😉
标签: 安全, 网络安全, Nodejs, Express, IDOR, 不安全直接对象引用, 会话, 认证, 授权, 开发, 编码
发表回复