A common use for Node.js is to build web applications. Usually, we want these applications to listen on port 80. As a security precaution, most OS’s require root privileges for this to happen (e.g. OS X, Linux, BSD). To run a Node application this way, we need to do the following:
sudo node server.js
Then, the application runs as root for the rest of the session. There are potential security risks to this, though. What if there is a vulnerability in your application and a hacker starts controlling your app and doing naughty things with it? Thankfully, we can drop the user account running our process to a less secured user, such as our normal account. There are two methods on the process global which can handle this for us, .setgid() and .setuid().
Here’s a working example of this in action. We want to run this code AFTER we bind to port 80, so we run the code in a callback:
app.listen(80, 'localhost', null, function() {
// Listening
try {
console.log('Old User ID: ' + process.getuid() + ', Old Group ID: ' + process.getgid());
process.setgid('users');
process.setuid('tlhunter');
console.log('New User ID: ' + process.getuid() + ', New Group ID: ' + process.getgid());
} catch (err) {
console.log('Cowardly refusing to keep the process alive as root.');
process.exit(1);
}
});
The results of .getuid() and .getgid() will be numeric, and aren’t really useful, other than showing that something happened. They’ll probably both say 0 the first time (that’s root in *nix land), and then some bigger number afterwards.
Unsure of your username or group name? For shame! Run the following commands:
whoami
groups