When writing command line tools, sometimes there is sensitive information (like passwords) on the command line that shouldn’t be visible right away in the process list. I know what you are thinking now “Passwords on the command line is a big fat NO”. Yeah maybe from security viewpoint this is a horrible thing to do, but from the usability perspective is pretty convenient. And as reality has proven so many times , convenience triumphs over security. But being a bit precautious won’t hurt, so let’s see how we can hide that password.
Process name in Node.js
Node.js has support for retrieving and setting the process name along with the passed command line argument. There is process.title property which according to the documentation is a getter/setter for the process name.
So our first guess is :
process.title = process.title.replace('HIDEME','******')
The result of this is not what you’d expect. It sets the process name and command line to just ‘node’. That’s because process.title contains only the process name and no command line arguments:
$ node -e 'console.log("process name=\"" + process.title + "\"") ; setTimeout("",10000)' arg1 arg2 arg3 process name="node" # In anohter shell $ ps ax ... 48146 s009 S+ 0:00.11 node -e console.log("process name=\"" + process.title + "\"") ; setTimeout("",10000) arg1 arg2 arg3 ...
Setting it will overwrite the both the process name and command line arguments though.
$ node -e 'process.title ="got nothing to hide"; console.log("process name=\"" + process.title + "\"") ; setTimeout("",10000)' arg1 arg2 arg3 process name="got nothing to hide" # $ ps ax ... 48151 s009 S+ 0:00.12 got nothing to hide ...
So we can overwrite the visible process name but we loose some information that might be nice to have like, what is this process, and what command line arguments it was ran with.
The good news is that we have the command line arguments in process.argv so all we have to do is reconstruct the command line and append it to process.title.
Change the visible process name
Here it goes:
// append the current process name to the new title var t = [ process.title ]; // Append the script node is running, this is always argv[1] // Also run it trough path.relative, because node replaces argv[1] // with its full path and this is way too long t.push( path.relative(process.cwd(), process.argv[1]) ); // For the rest of the argv for(var index=2; index < process.argv.length; index++ ) { var val = process.argv[ index ]; // If the current argument is the password if(val === 'password' ) { // Append stars t.push( val.replace(/./g, '*') ); } else { // Else append the argument as it is t.push( val ); } } // Finaly set the visible title process.title = t.join(' ');
This works quite well if you don’t change the length of the command line. Making it shorter also works fine, but making it longer will lead to truncated string as the memory for argv is preallocated by the C runtime, and Node just overwrites that, meaning it cannot change its length.
Running this with ‘password’ on the command line gives:
$ node process_title.js argv1 argv2 password argv4 # Check the visible name $ ps ax 48327 s010 S+ 0:00.10 node process_title.js argv1 argv2 ******** argv4
I don’t experience the same result on Windows. The process name seems unafected by this approach. Do you suspect I did something wrong, or is this only working on UNIX based operating systems?
Haven’t tested on Windows , but I would suspect it won’t work there. Processes are quite different in Windows and for sure will require a different mechanism if possible at all.