session-file-store库的session伪造
字数 1578 2025-08-26 22:11:35
Session-File-Store 库的 Session 伪造漏洞分析
1. 前言
Node.js 的 session-file-store 库是一个依赖于 Express 或其他中间件的第三方库,它为 Express Session 提供了文件存储接口。当没有为 Session 合理配置密钥或 Session 配置文件泄露时,可能导致 Session 伪造漏洞。
2. Session 机制基础
HTTP 是一种无状态协议,服务端无法根据之前的状态处理当前请求。为解决这个问题,引入了 Cookie 技术:
- Cookie 是存储在客户端的键值对
- 客户端可以随意修改 Cookie 内容
- 敏感信息不适合直接存储在 Cookie 中
Session 机制是基于 Cookie 的特殊实现方案:
- 服务端指定一个 Cookie 键作为 Session 键(如 "SESSION")
- 对应的值是服务端生成的随机字符串(SESSIONID)
- 服务端通过 SESSIONID 与客户端状态绑定进行认证
- 客户端状态可以存储在文件、数据库或内存中
Session 机制既防止了客户端修改状态数据,又避免了敏感数据泄露。
3. Session-File-Store 的 Session 伪造
漏洞前提条件
- 存在任意文件读取或文件上传漏洞
- 通过爆破或配置文件泄露获取 Session 签名密钥
Session 文件存储方式
session-file-store 将 Session 以 JSON 文件形式明文存储,例如:
{
"cookie": {
"originalMaxAge": null,
"expires": null,
"httpOnly": true,
"path": "/"
},
"views": 4,
"__lastAccess": 1554220794810
}
签名机制分析
签名实际上是签在 SessionID 上,而非 Session 内容。签名验证由 express-session 库完成:
签名生成代码 (express-session/index.js):
function setcookie(res, name, val, secret, options) {
var signed = 's:' + signature.sign(val, secret);
var data = cookie.serialize(name, signed, options);
res.setHeader('set-cookie', header)
}
签名验证代码 (express-session/index.js):
function getcookie(req, name, secrets) {
if (raw.substr(0, 2) === 's:') {
val = unsigncookie(raw.slice(2), secrets);
if (val === false) {
debug('cookie signature invalid');
val = undefined;
}
}
return val;
}
Session 文件读取漏洞
session-file-store 读取 Session 文件的关键代码路径:
FileStore.prototype.get调用helpers.gethelpers.get通过helpers.sessionPath获取文件路径sessionPath函数简单拼接路径,无安全过滤:
sessionPath: function (options, sessionId) {
return path.join(options.path, sessionId + options.fileExtension);
}
漏洞利用步骤
-
准备恶意 Session 文件:
- 修改
views等字段为所需值 - 更新
__lastAccess时间戳
- 修改
-
获取签名 SessionID:
- 使用泄露的密钥对伪造的 SessionID 签名
- 签名脚本示例:
var signed = 's:' + signature.sign(val, secret); var data = cookie.serialize(name, signed, options); console.log(data);
-
上传恶意 Session 文件:
- 通过文件上传漏洞将伪造的 Session 文件上传
- 利用路径遍历使文件位于可访问位置(如
../upload/)
-
修改客户端 SessionID:
- 使用 Burp 等工具将 Session Cookie 修改为签名的伪造 SessionID
防御措施
-
保护签名密钥:
- 使用强密钥并妥善保管
- 避免密钥泄露在配置文件中
-
安全配置 Session:
app.use(session({ store: new FileStore(), secret: '强随机密钥', // 使用强随机密钥 resave: false, saveUninitialized: false, rolling: true, cookie: { secure: true, // 仅HTTPS httpOnly: true, // 防止XSS sameSite: 'strict' // CSRF防护 } })); -
输入验证:
- 对 SessionID 进行严格验证
- 防止路径遍历攻击
-
文件权限控制:
- 限制 Session 目录的读写权限
- 隔离上传目录与 Session 目录
-
使用更安全的存储方式:
- 考虑使用 Redis 等内存数据库存储 Session
- 避免明文存储敏感信息
4. 总结
session-file-store 的 Session 伪造漏洞主要源于:
- Session 文件明文存储
- 路径拼接无安全过滤
- 签名仅验证 SessionID 而非内容
通过合理配置和安全编码实践,可以有效防范此类漏洞。开发者应始终遵循最小权限原则和安全编码规范,确保 Session 管理机制的安全性。