Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Importance of session secret key in Express web framework

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)
like image 750
gluxon Avatar asked Sep 02 '13 04:09

gluxon


People also ask

What is secret key in express session?

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.

What is the use of session in express?

The session middleware handles all things for us, i.e., creating the session, setting the session cookie and creating the session object in req object. Whenever we make a request from the same client again, we will have their session information stored with us (given that the server was not restarted).

What should session secret?

The secret should be a random string of characters. Ideally you would also change it periodically in case it has been discovered. However, this requires support for secret rotation so you don't immediately invalidate existing sessions. That is, two session secrets should be considered valid simultaneously.

How long should a session secret be?

A string of random alnum characters, say 24 to 32 bytes long, should do just fine.


2 Answers

  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.

like image 67
Mike 'Pomax' Kamermans Avatar answered Oct 05 '22 03:10

Mike 'Pomax' Kamermans


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.

like image 25
argaz Avatar answered Oct 05 '22 01:10

argaz