Search code examples
javascriptnode.jsexpresssessionsession-cookies

express-session should secret be static or dynamic?


I can't find any information from the documentation whether the secret should be a static string or if it should/can be dynamic. Here's how I'm setting the secret right now.

var salt1 = bcrypt.genSaltSync();
var salt2 = bcrypt.genSaltSync();
var secret = bcrypt.hashSync(salt1 + salt2, 10);
app.use(session({
    // activeDuration: toTime("days", 7),
    // duration: toTime("days", 7),
    maxAge: toTime("days", 7),
    saveUninitialized: false,
    secret, // set this to a long random string!,
}));

So should the secret be a one time thing or can it be dynamic?


Solution

  • Usually these secrets are used to sign and/or encrypt session data stored in client-side cookies (in case of express it's used to sign the session data to prevent tampering).

    So the secret must be:

    • secret (duh!)
    • static (changing it will invalidate any session using the old secret unless you keep the old ones around as well)
    • configurable, just like DB credentials etc. (you don't want to commit secrets to your codebase)
    • random (anything that gives you a long random/unpredictable string is fine)

    FYI, using bcrypt to generate it makes no sense. bcrypt's goal is to be slow to prevent brute-forcing hashes. This is not relevant here. Proper randomness is enough.


    Relevant section from the docs:

    This is the secret used to sign the session ID cookie. This can be either a string for a single secret, or an array of multiple secrets.

    If an array of secrets is provided, only the first element will be used to sign the session ID cookie, while all the elements will be considered when verifying the signature in requests.


    Since express-session supports keeping old secrets around, you could rotate the active secret. For example, once a month you could prepend a new random secret to the array and thus allow existing sessions with the old secret to keep working while not using it for any new sessions. Then, once your max age has been reached, you can safely remove a secret not used for that many days. Like this an accidental leak of a session secret would become harmless after some time (unless someone abused it in the meantime of course)