Express Web 框架中会话密钥的重要性

Posted

技术标签:

【中文标题】Express Web 框架中会话密钥的重要性【英文标题】:Importance of session secret key in Express web framework 【发布时间】:2013-09-05 02:35:19 【问题描述】:

我对会话密钥的重要性感到很困惑。我正在使用 Express 和 Node 进行 Web 开发,目前,我正在尝试实现一个简单的登录。以下代码取自 Express 中的会话示例。

// Required by session() middleware
// pass the secret for signed cookies
// (required by session())
app.use(express.cookieParser('keyboard cat'));

// Populates req.session
app.use(express.session());

它使用“键盘猫”作为会话秘密。我环顾四周的关于会话秘密的许多事情都建议我将其更改为自定义的东西。我现在有 3 个与此相关的具体问题。

    为什么我以前使用 php 时没有看到这个? 会话密钥的具体用途是什么? 假设我更改了会话密钥。我的代码是开源的。在那种情况下,改变它会不会有点多余?我没有看到要求用户提供自定义键作为选项。 我正在考虑生成一个随机 UUID 来填充密钥。这有问题吗? (在安全方面)

【问题讨论】:

我认为标记的答案没有抓住重点,即secret 是否使会话更加安全。我建议访问security.stackexchange.com/questions/92122/… 进行更深入的讨论(不仅是相关的最高投票答案)。 @argaz 我发现该链接非常有用。您愿意添加您的评论作为答案吗? 【参考方案1】:
    因为 PHP 不是 Nodejs。 PHP 中的会话管理与节点中的会话管理不同:节点永不消亡,与 PHP 不同,PHP 会不断地由您的服务器守护程序(apache、IIS、您有什么)调用,要求生成一些内容,然后结束其进程。 Node 相当于 Apache plus PHP。 它用于加密会话 cookie,以便您可以合理(但不是 100%)确定 cookie 不是假的,并且应将连接视为与 express 的较大会话的一部分。 这就是为什么不将字符串放在源代码中的原因。您将其设置为环境变量并将其作为 process.env("SESSION_SECRET") 读入,或者使用带有https://npmjs.org/package/dotenv 的.env 文件,并确保这些文件永远不会触及您的存储库(svn/git exclude/ignores)所以确保您的秘密数据保密。 当您的节点应用程序运行时,密钥是不可变的。提出一个长而有趣的句子比 UUID 要好得多,UUID 通常比 "I didn't think I needed a secret, but some rando on *** told me Express needed one so here we are" 短得多。

我如何使用会话:

.env 文件(始终在我的 .gitignore 文件中,因此它永远不会访问我的公共存储库):

SECRET="This is my funky secret oh my god it has ninja turtles"

app.js:

var express = require('express'),
    env = (function()
      var Habitat = require("habitat");
      Habitat.load();
      return new Habitat();
    ()),
    app = express();

app.use(express.compress()); // gzip all the things. If possible.
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.cookieSession(
  key: "mysite.sid",
  // seeing this tells you nothing about the actual secret:
  secret: env.get("SESSION_SECRET"),
  cookie: 
    maxAge: 2678400000 // 31 days
  
));
app.use(express.csrf());

该 CSRF 位确保页面请求来自您自己的站点,而不是 cURL 请求或嵌入到其他人的网站。 http://expressjs.com/api.html#csrf 了解更多信息。

【讨论】:

我了解 PHP 和 Node.js 之间的区别。我只是不明白为什么这种差异会导致不同的会话管理。我觉得 PHP 在运行时会生成一个随机会话密钥,或者从 Apache 中获取一个。就像我说的,如果可能的话,我宁愿不要让我的用户设置会话密码。 @gluxon 确实如此。一个 uuid 通常是一个多字符的十六进制字符串,如果你幸运的话,或者一个长整数,如果你不幸运的话。适当长的短语更长,符号域更大。因此它更长,更多样化。至于您的用户选择会话秘密,他们不是。你是。您的用户永远看不到它。 尽管这个答案很彻底,但它忽略了一个基本问题:PHP 和 node.js 管理会话的方式有什么不同?如果解决了这个问题,这个答案将大大改善。 (答案当然是客户端会话与服务器端会话。) 有点晚了 2 年?也就是说,我会说“不要将答案标记为正确,因为社区支持它”。投票是社区的声音,但接受答案是你的声音:投票给找到回答你的问题的人,因为这就是 *** 的问答结构的全部意义= ) 我认为这个答案没有抓住重点,即secret 是否使会话更加安全。我建议访问security.stackexchange.com/questions/92122/… 进行更彻底的讨论(不仅是相关的最高投票答案)。【参考方案2】:

我认为其他答案中遗漏了主要观点,即secret 参数是否使会话管理更加安全。在这个 Security.StackExchange 问题中很好地讨论了它:Why is it insecure to store the session ID in a cookie directly?

我建议阅读它(不仅有相关的最高投票答案)。

尝试总结一下:如果 会话 ID 是大随机数,它不会显着降低会话被猜测和劫持的机会,但如果会话 ID 是自定义的,例如递增的 ID,这在 ExpressJS 中是可能的。

用户可以使用他们想要的任何会话 ID。也许有人觉得他们应该使用 SQL 数据库中的自动递增数字,这没关系,因为我们通过签名值、延长密钥来保护他们不知情的决定。

【讨论】:

【参考方案3】:

我的困惑在于服务器端会话和客户端会话。在今天之前,我不知道客户端。以下是对差异的清晰解释。

Why CherryPy session does not require a secret key?

想到服务器端模型,我很困惑会话中需要加密的地方。

【讨论】:

以上是关于Express Web 框架中会话密钥的重要性的主要内容,如果未能解决你的问题,请参考以下文章

express中间件

播放框架中的会话处理

express中间件的理解

Express 中跨子域的会话

PHP之ThinkPHP框架(会话)

Express源码解析之next