Chris Jeong Chris Jeong - 1 month ago 10
Node.js Question

Is it OK to generate session secret(or any other secret keys) and store it in host server?

I'm testing Google OAuth2.0 on node.js + express and using express-session for managing session, and I came across that I need Secret Key for my session manager.

So I did some research and found a post, which has some nice suggestions. But it seems to require some workarounds, like setting secret key as environment variable or keeping it in configuration file.


  • Using the former, I need to enter environment variables every time I redeploy sever.

  • Using the latter exposes my secret key to SCM.



So I decided to generate random string and store it in the host file system. It seems to solve all the problems I introduced above, but I'm noob to web development so I'm not sure whether this is legit.

Is there any cons or exploit to this method?

Below is my
sessionSecret.js
file:

var crypto = require('crypto');
var fs = require('fs');

var filePath = '/home/ubuntu/results.txt';

function readSecretKey() {
return new Promise(function(resolve, reject) {
fs.readFile(filePath, 'utf8', function(err, key) {
if (err) {
reject(err);
} else {
resolve(key);
}
});
});
}

function writeSecretKey(key) {
return new Promise(function(resolve, reject) {
fs.writeFile(filePath, key, function(err) {
if (err) {
reject(err);
} else {
resolve(key);
}
});
});
}

function generateRandomString() {
return new Promise(function(resolve, reject) {
crypto.randomBytes(48, function(err, buf) {
if (err) {
reject(err);
} else {
resolve(buf.toString('hex'));
}
})
});
}

module.exports.getOrCreate = function() {
return new Promise(function(resolve, reject) {
readSecretKey()
.then(function(key) {
console.log("Key exists: " + key);
resolve(key);
}, function() {
console.log("Key does not exists. Generating...");
return generateRandomString();
})
.then(function(key) {
if (key) {
console.log("Key generated: " + key);
return writeSecretKey(key);
}
}).then(function(key) {
if (key) {
resolve(key);
}
}, function(err) {
reject(err);
});
});
};

Answer

Your intuition is correct.

Passing secrets in as an environment variable is just moving the problem outside the app. You have to have them somewhere anyway.

Passing them as an argument is less secure than a file, because any user on the server can ps aux and see them.

The only thing you did wrong in my opinion is overcomplicating it. I recommend dropping most of the code from the sessionSecret.js and instead of generating it on the fly, just get it from the config file. Shutdown the app if config file is not there.

Don't store the secrets in repository/SCM I put my secrets in a special folder in /etc/ of the server. If someone gets access to that, stealing sessions is the least they can do.