tags:

views:

122

answers:

5

Hi,

I have the following problem:

I've a script that launch inside of itself a command with a parameter that is a secret.

For example:

#!/bin/bash
command secret

While running the command I can read through ps -ef | grep command which is the secret.

Is ther any way of hiding the secret in a way that through ps -ef the command line parameter is offuscated?

Thanks!

+2  A: 

There's no easy way. Take a look at this question I asked a while ago:

http://stackoverflow.com/questions/724582/hide-arguments-from-ps

Is command your own program? You could try encrypting the secret and have the command decrypt it before use.

dogbane
in your case the problem was overcome by configuring ad-hoc the conf for reading the private key by default. In this case the problem is differente.
Kerby82
@Kerby82: no - the situation is the same; there is no way to hide command line options from 'ps'.
Jonathan Leffler
+1  A: 

The only way to conceal your secret argument from ps is not to provide the secret as an argument. One way of doing that is to place the secret in a file, and to redirect file descriptor 3 to read the file, and then remove the file:

echo secret > x.$$
command 3<x.$$
rm -f x.$$

It isn't entirely clear that this is a safe way to save the secret; the echo command is a shell built-in, so it shouldn't appear in the 'ps' output (and any appearance would be fleeting). Once upon a very long time ago, echo was not a built-in - indeed, on MacOS X, there is still a /bin/echo even though it is a built-in to all shells.

Of course, this assumes you have the source to command and can modify it to read the secret from a pre-opened file descriptor instead of from the command line argument. If you can't modify the command, you are completely stuck - the 'ps' listing will show the information.

Another trick you could pull if you're the command owner: you could capture the argument (secret), write it to a pipe or file (which is immediately unlinked) for yourself, and then re-exec the command without the secret argument; the second invocation knows that since the secret is absent, it should look wherever the first invocation hid the secret. The second invocation (minus secret) is what appears in the 'ps' output after the minuscule interval it takes to deal with hiding the secret. Not as good as having the secret channel set up from the beginning. But these are indicative of the lengths to which you have to go.

Zapping an argument from inside the program - overwriting with zeroes, for example - does not hide the argument from 'ps'.

Jonathan Leffler
I'd add a `umask 077` before the echo to ensure that only the user can read the file.
JeremyP
@Jeremy - good suggestion.
Jonathan Leffler
+1  A: 

The expect library was created partially for these kind of things, so you can still provide a password / other sensitive information to a process without having to pass it as an argument. Assuming that when 'secret' isn't given the program asks for it of course.

Wrikken
+1  A: 

If the script is intended to run manually, the best way is to read it in from STDIN

#!/bin/bash
read -s -p "Enter your secret: " secret

command "$secret"
Daenyth
Bash 2.04 and greater have `read -s` which doesn't echo the input characters so you only need to use stty with shells that don't have that (zsh also has it).
Dennis Williamson
@Dennis Williamson: Nice, I didn't know that! Thanks
Daenyth
The trouble with this is that the secret is exposed on the command line and will show up in `ps` output - but the question is asking how to avoid that exposure.
Jonathan Leffler
@Johnathan: Aha, I see what you mean. If you combine this with your answer below it's a way to do it though.
Daenyth
+1  A: 
Kelly French
'The command line will only show the given environment variable, not its value' -- These comments are **WRONG** on two counts. First, dotting the ~/.appsecrets file has reset the command line arguments of the shell to have just one, the value of $1 is now 'SECRET=polkalover'; there is no variable, let alone environment variable, called SECRET. Secondly, if you get a variable SECRET created (not hard), running 'command $SECRET' expands $SECRET before executing the command, and `ps` shows the expanded version of the information.
Jonathan Leffler
@jonathan - you are right. I was thinking about the C++ approach mainly. I've updated my answer to show the script approach.
Kelly French