In the options to set up the session there's a secret key:
app.use(session({
secret: 'keyboard cat',
...
});
I don't completely understand what the secret is or why it's needed but it seems that hiding its value from everyone is important for security.
How can I securely generate and use random secrets with this middleware?
And is there a way to change (rotate) the secret every-so-often?
The easiest way would be to supply it via a node environment variable. So instead of just running node server.js, you run SESSION_SECRET=mylittlesecret node server.js.
You can access environment variables in you application like this:
app.use(session({
secret: process.env.SESSION_SECRET,
...
});
You might want to check whether this secret exists because if it doesn鈥檛 this will leave your application vulnerable.
As for rotating, the easiest way to do this is manually or if you鈥檙e running something like Heroku you can often do it via command line tools.
Please note that once you rotate your secret, all active sessions will become invalid. Basically, all your users will be logged out.
More info about environment variables can be found here: https://www.twilio.com/blog/2017/08/working-with-environment-variables-in-node-js.html
@mattijsbliek rotating with an environment variable would require the app to be restarted.
I think that keeping the secret internal (i.e. not an environment variable) is more secure and also easier to manage. Keep in mind I want to automate secret creation, this can be done from within node so what's the point of the environment variable?
As for rotating and invalidating previous sessions, I know that session now allows you to set the secret to an array of valid secrets.
@theonlygusti I would not recommend keeping the secret internal, by which I鈥檓 assuming you mean in memory. This would make your application stateful, which is problematic if:
You could theoretically store your secrets in a database or key/value store and do a lookup on each request. One option for doing this would be to wrap the session middleware in a custom middleware which performs the secret lookup and the invokes the session middleware with the retrieved secret. Something like this:
app.use(async (req, res, next) => {
// retrieve secrets from store
const sessionSecrets = await Store.getSessionSecrets();
session({
secret: sessionSecrets,
// ...other options
})(req, res, next);
})
But personally I would go with environment variables and something like PM2鈥檚 reload command for 0-second-downtime reloads.
Hope this helps! Also, all this stuff might already be familiar to you. I don鈥檛 mean to sound condescending in any way 馃檪
Thanks @mattijsbliek. You Helped me a lot!
Most helpful comment
@theonlygusti I would not recommend keeping the secret internal, by which I鈥檓 assuming you mean in memory. This would make your application stateful, which is problematic if:
You could theoretically store your secrets in a database or key/value store and do a lookup on each request. One option for doing this would be to wrap the session middleware in a custom middleware which performs the secret lookup and the invokes the session middleware with the retrieved secret. Something like this:
But personally I would go with environment variables and something like PM2鈥檚 reload command for 0-second-downtime reloads.
Hope this helps! Also, all this stuff might already be familiar to you. I don鈥檛 mean to sound condescending in any way 馃檪