北京网站建设签约,福建省住建厅网站官网,自媒体是干什么的,张北网站seo什么是会话固定以及如何在 Node.js 中防止它
在深入讨论之前#xff0c;我们需要了解会话是什么以及会话身份验证如何工作。
什么是会话#xff1f;
正如我们所知#xff0c;HTTP 请求是无状态的#xff0c;这意味着当我们发送登录请求时#xff0c;并且我们有有效的用…什么是会话固定以及如何在 Node.js 中防止它
在深入讨论之前我们需要了解会话是什么以及会话身份验证如何工作。
什么是会话
正如我们所知HTTP 请求是无状态的这意味着当我们发送登录请求时并且我们有有效的用户名和密码没有默认机制可以知道我们是发送下一个请求的同一个人。为了解决这个问题换句话说使请求有状态有一些常用的方法如Cookie、隐藏表单字段、URL 参数、浏览器存储、JWT 和 Session。在本文中我们将重点关注Session。
Session是存储在服务器上的数据。每个客户端都会获得一个与服务器上的数据相关的唯一标识符 。客户端必须在每个请求上发送此唯一标识符以便我们知道谁发送了此请求。该标识符可以在 cookie 或 URL 参数中发送。
下面是使用express-session和express创建session的简单示例
const app require(express)();
const session require(express-session);
app.use(require(cookie-parser)());
app.use(require(body-parser).json());app.use(session({secret: secret,cookie: { maxAge: 60000 },name: sessionId
}));app.get(/, (req, res) {res.send(ping);
});app.listen(3000, () {console.log(Server is running on port 3000);
});当第一次发送请求时express-session中间件会创建一个新的唯一标识符并将其设置为 cookie 后再将其存储在某处在本例中为内存但我们也可以传递自定义存储。在会话中间件的选项中我们使用了sessionId存储此唯一标识符的密钥名称。现在如果我们发送请求我们会看到如下内容 浏览器现在设置此 cookie 并自动存储它以供进一步请求。如果我们发送包含有效会话的请求该会话存在于我们的会话存储中 - 在本例中为内存在响应中获取标头的标头就不再包含Set-Cookie字段了 当用户登录时我们可以将用户信息存储在 cookie 中序列化也可以将其存储在数据库中并将数据与sessionId进行绑定. 让我们使用 Map 作为我们的简单数据库
const db new Map();
app.get(/me, (req, res) {const user db.get(req.sessionID);res.json({ mySessionId: req.sessionID, me: user ? user : anonymous });
});
const users [{ name: leo, age: 19 }, { name: joe, age: 20 }];
app.post(/login, (req, res) {const { name } req.body;const user users.find(u u.name name);if (user) {db.set(req.sessionID, user);res.send(ok);} else {res.send(try again);}
});攻击者可以创建有效的会话 ID 吗
在本例中我们使用的是express-session。可以看到我们向express-session中间件传递了一个secret值。这个secret用于签署我们的 cookie 的值。它只是意味着我们确信是我们生成了sessionId。
session示例
sessionIds%3AL6j4T8hBwMk1ulJqGoisZbAxUOkOuQqP.x5UxPQEtKrj3sWrIy6S01CQRjAtp4biVs4H2zgqmSs第一部分s%3A简单来说s:这是一个前缀表明我们的 cookie 会话已签名
第二部分L6j4T8hBwMk1ulJqGoisZbAxUOkOuQqP这是我们的sessionId我们在数据库中使用它来关联数据。
第三部分x5UxPQEtKrj3sWrIy6S01CQRjAtp4biVs4H2zgqmSs这是签字部分。我们使用我们的secret生成了此文本因此我们可以确定此 cookie 是由我们生成的。
我们可以简单地重新生成这个标志并检查它是否有效
const crypto require(crypto);
const secret secret;
const sessionId L6j4T8hBwMk1ulJqGoisZbAxUOkOuQqP;
const hmac crypto.createHmac(sha256, secret);
hmac.update(sessionId);
const signature hmac.digest(base64).replace(/\$/, );
console.log(signature); // x5UxPQEtKrj3sWrIy6S01CQRjAtp4biVs4H2zgqmSs什么是会话固定
在会话固定攻击中攻击者劫持有效的用户会话。我们说过我们对 cookie 进行签名是为了确保没有人可以劫持其他用户的有效会话。但是如果攻击者拥有自己的有效会话并尝试将其与另一个用户关联怎么办在这种情况下他可以代表受害者采取行动。
当我们没有在 Login 之类的操作上生成新的 sessionIds唯一标识符时就会出现问题。
通过会话固定攻击者可以劫持有效的用户会话了解此漏洞并防范它绝对重要。
攻击者如何才能做到这一点
其中一种情况是攻击者可以物理访问计算机。作为攻击者我们可以选择一台共享计算机打开某个已经登录过的网页然后复制session后发送请求。
sessionId在有些网站在请求中作为 URL 参数传递。在这种情况下如果攻击者使用其 URL 参数提供登录页面的链接sessionId则有可能被利用。
如何防止会话固定
登录时生成新会话
主要解决方案非常简单通过这样做始终可以确保不会发生此会话覆盖
让我们改变代码
app.post(/login, (req, res) {const { name } req.body;req.session.regenerate(err {if (err) {res.send(error);} else {const user users.find(u u.name name);if (user) {db.set(req.sessionID, user);res.send(ok);} else {res.send(try again);}}});
});我们可以使用regenerate函数以便每次有人想要登录时分配一个新的会话。无论我们是否传递会话cookie它都会生成一个新的会话Id并将其发送到客户端中。
仅使用HTTP Only 的 Cookie
当我们使用HTTP Only时这意味着只有服务器可以通过Set-Cookie标头设置cookie而客户端浏览器JavaScript无法更改它。所以即使我们的应用存在XSS漏洞攻击者也无法更改sessionIdcookie。
防范 XSS
会话固定可以与 XSS 攻击结合使用从而更加有效因此如果我们担心会话固定那么认真对待 XSS 攻击确实有意义。
合理的会话过期时间
会话过期时间应该符合我们的应用程序特定要求如果我们更关心安全性那么它应该更短反之亦然。
正确的注销实施
注销时我们必须正确销毁现有会话及其与任何数据的关联。否则这些会话可以在注销后使用。仅从客户端浏览器中删除 cookie 是不够的