33

I'm quite confused by the importance of a session secret. I'm jumping into web development with Express and Node, and at the moment, I'm trying to implement a simple login. The below code is taken from the sessions example in 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());

It uses "keyboard cat" as a session secret. Many of the things I've looked around about session secrets recommend me to change this to something custom. I now have 3 specific questions concerning this.

  1. Why have I not seen this before when I was working with PHP?
  2. What is the session secret being used for exactly?
  3. Let's say I change the session key. My code is open source. Won't changing this be a bit redundant in that case? I don't see asking the user for a custom key as an option.
  4. I was thinking of generating a random UUID to fill in the key. Are there problems with this? (in terms of security)
gluxon
  • 750
  • 1
  • 7
  • 16
  • 1
    I think that the marked answer is missing the point, which is whether the `secret` is making sessions more secure. I suggest visiting http://security.stackexchange.com/questions/92122/why-is-it-insecure-to-store-the-session-id-in-a-cookie-directly for a more thorough discussion (not only the top voted answer there is relevant). – argaz Jul 27 '16 at 21:09
  • @argaz I found that link to be really informative. Would you be willing to add your comment as an answer? – gluxon Aug 02 '16 at 01:11

3 Answers3

43
  1. Because PHP is not Nodejs. Session management in PHP is different from session management in node: node never dies, unlike PHP, which is constantly invoked by your server daemon (apache, IIS, what have you), asked to generate some content, then end its process. Node is the equivalent of Apache plus PHP.
  2. It's used to encrypt the session cookie so that you can be reasonably (but not 100%) sure the cookie isn't a fake one, and the connection should be treated as part of the larger session with express.
  3. This is why you don't put the string in your source code. You make it an environment variable and read it in as process.env("SESSION_SECRET") or you use an .env file with https://npmjs.org/package/dotenv, and make sure those files never touch your repository (svn/git exclusion/ignores) so that your secret data stays secret.
  4. the secret is immutable while your node app runs. It's much better to just come up with a long, funny sentence than a UUID, which is generally much shorter than "I didn't think I needed a secret, but some rando on Stackoverflow told me Express needed one so here we are".

How I use sessions:

.env file (always in my .gitignore file so it never hits my public repos):

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());

That CSRF bit ensures that page requests are coming from your own site, not cURL requests or embeds in other people's websites. http://expressjs.com/api.html#csrf for more info on that.

Mike 'Pomax' Kamermans
  • 49,297
  • 16
  • 112
  • 153
  • 1
    I understand the difference between PHP and Node.js. I'm just not understanding why that difference would result in different session management. I feel like PHP generates a random session secret when it runs, or grabs one from Apache. Like I said, I would much rather not ask my user to set a session secret if possible. – gluxon Sep 02 '13 at 05:23
  • Also, why would a long string be more secure than a a uuid string? Doesn't variability > length? – gluxon Sep 02 '13 at 05:26
  • 2
    @gluxon it does. A uuid is typically a several character hex string, if you're lucky, or a long int, if you're not. a Properly long phrase is longer, with a larger symbol domain. It's thus longer, and more varied. As for your users picking a session secret, they're not. You are. Your users never get to see it. – Mike 'Pomax' Kamermans Sep 02 '13 at 15:55
  • 2
    As thorough as this answer is, it misses the fundamental question: What is different about how PHP and node.js manage sessions? This answer would vastly improve if it addressed that. (The answer, of course, being client-side vs. server-side sessions.) – Kittsil May 17 '16 at 18:09
  • no, that question has the answer "PHP uses `$_SESSION`, look up its documentation on https://php.net, and Node.js uses nothing: individual frameworks, built on top of Node.js, can add their own session management; look up how they do that in *their* documentation". PHP can't do in-memory server side session management because of how PHP works: it's asked to run a script by a persistent process like IIS/Apache/etc, it outputs data, then it ends. Node.js, on the other hand, *is* the persistent process upon which server software is built. – Mike 'Pomax' Kamermans May 17 '16 at 18:13
  • @Mike'Pomax'Kamermans I've changed the accepted answer to yours after looking at the community response in upvotes. I do agree with Kittsil that the answer would benefit from an explanation of client-side vs server-side cookies. Please take a look at another StackOverflow question on PHP cookies. They aren't in memory, but do persist on the server side. http://stackoverflow.com/questions/454635/where-are-session-variables-stored It is in fact, express that does not persist them on the server. – gluxon Jul 21 '16 at 18:15
  • I might add that Node.js and PHP are both capable of doing cookies client-side and server-side. It's true that they have different execution models, but that does not affect their ability to handle cookies in both ways. – gluxon Jul 21 '16 at 18:17
  • 1
    Kind of jumping on this 2 years too late? That said, I'd say "don't mark an answer as correct because the community upvotes it". Votes are the community's voice, but accepting an answer is *your* voice: vote the one that *you* found answered your question, because that's what the Q&A structure of Stackoverflow is all about =) – Mike 'Pomax' Kamermans Jul 21 '16 at 18:40
  • It has been some time, but I saw your response to Kittsil and wanted to add information. My personal preference is that my own answer (while made sense to me 3 years ago) is lacking detail now. What's your response to PHP serving cookies server-side? – gluxon Jul 22 '16 at 04:55
  • none, really. you gave a link you thought is relevant, so that's good enough for me. If someone else runs into this later and finds it lacking (reactively, not preemptively) they can request more information with a comment. – Mike 'Pomax' Kamermans Jul 22 '16 at 16:11
  • 1
    I think that this answer is missing the point, which is whether the `secret` is making sessions more secure. I suggest visiting http://security.stackexchange.com/questions/92122/why-is-it-insecure-to-store-the-session-id-in-a-cookie-directly for a more thorough discussion (not only the top voted answer there is relevant). – argaz Jul 27 '16 at 21:06
  • this answer was specifically for the *actual* questions asked in the post, not the one implied by the title. For that, your link is great. – Mike 'Pomax' Kamermans Jul 27 '16 at 21:41
13

I think that the major point is missed in the other answers, which is whether the secret parameter is making session management more secure. it is discussed nicely in this Security.StackExchange question: Why is it insecure to store the session ID in a cookie directly?

I recommend reading it (not only the top voted answer there is relevant).

Trying to sum it up: it won't reduce segnificantly the chances of a session being guessed and hijacked in case that the session IDs are large random numbers, but it will obviously help greatly if the session IDs are custom like incrementing IDs, which is possible in ExpressJS.

Users can use whatever session IDs they want. Perhaps someone feels like they should use an auto incrementing number from the SQL database, it doesn't matter, because we protect their uninformed decision by signing the value, elongating the key.

Community
  • 1
  • 1
argaz
  • 1,458
  • 10
  • 15
3

My confusion was between server-side sessions and client-side sessions. Before today, I had not known about client-side. A clear explanation of the difference is found below.

Why CherryPy session does not require a secret key?

Thinking of the server-side model, I was very confused where encryption would be required in sessions.

Community
  • 1
  • 1
gluxon
  • 750
  • 1
  • 7
  • 16