7

If I use a password as a command-line parameter it's public on the system using ps.

But if I'm in a bash shell script and I do something like:

...
{ somecommand -p mypassword }
...

is this still going to show up in the process list? Or is this safe?

  • How about sub-processes: (...)? Unsafe right?
  • coprocess?
David Parks
  • 30,789
  • 47
  • 185
  • 328

4 Answers4

8

Command lines will always be visible (if only through /proc).

So the only real solution is: don't. You might supply it on stdin, or a dedicated fd:

./my_secured_process some parameters 3<<< "b@dP2ssword"

with a script like (simplicity first)

#!/bin/bash
cat 0<&3

(this sample would just dump a bad password to stdout)

Now all you need to be concerned with is:

  • MITM (spoofed scripts that eaves drop the password, e.g. by subverting PATH)
  • bash history retaining your password in the commandline (look at HISTIGNORE for bash, e.g.)
  • the security of the script that contains the password redirection
  • security of the tty's used; keyloggers; ... as you can see, we have now descended into 'general security principles'
sehe
  • 374,641
  • 47
  • 450
  • 633
  • Is the 3 above a typo? Should it just be << If not, what does the 3 signify? – q0rban Nov 30 '12 at 15:25
  • Ok, I think I get it. That is the number of the argument? I think it's supposed to be a 2, though, not a 3. The first argument would be 0, second 1, third 2. Is that correct? – q0rban Nov 30 '12 at 15:30
  • 1
    Nope. `<<<` means: Stream this text to stdin. `3<<<` means: stream this text to _filedescriptor 3_. As you can see with the demo script, you can then read `fd 3` from the script. This is security by obscurity because stdin/stdout/stderr are the only _standard_ (usual) shell pipe filedescriptors. – sehe Nov 30 '12 at 16:05
  • To be frank, this doesn't really buy you much as the input will still end up being sent to `cat` (in the sample) on stdin... (_filedescriptor_ `0`). But at least it doesn't show up on the commandline in `ps`, `top`, /proc/... – sehe Nov 30 '12 at 16:07
  • 4
    [Apparently](http://unix.stackexchange.com/a/181996), "here-strings in bash are implemented as deleted temporary files". If that means they can make it to disk, it is another security consideration. Might be better to use process substitution [like here](http://stackoverflow.com/a/24455773): `./my_secured_process some parameters 3< <(printf '%s\n' b@dP2ssword)` – tanius Jul 24 '16 at 22:23
4

How about using a file descriptor approach:

env -i bash --norc   # clean up environment
set +o history
read -s -p "Enter your password: " passwd
exec 3<<<"$passwd"
mycommand <&3  # cat /dev/stdin in mycommand

See:

Hiding secret from command line parameter on Unix

Community
  • 1
  • 1
puja
  • 41
  • 1
3

The called program can change its command line by simply overwriting argv like this:

#include <stdlib.h>
#include <string.h>

int main(int argc, char** argv) {
    int arglen = argv[argc-1]+strlen(argv[argc-1])+1 - argv[0];
    memset(argv[0], arglen, 0);
    strncpy(argv[0], "secret-program", arglen-1);
    sleep(100);
}

Testing:

$ ./a.out mySuperPassword & 
$ ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
me       20398 18872  0 11:26 pts/3    00:00:00 bash
me       20633 20398  0 11:34 pts/3    00:00:00 secret-program
me       20645 20398  0 11:34 pts/3    00:00:00 ps -f
$

UPD: I know, it is not completely secure and may cause race conditions, but many programs that accept password from command line do this trick.

Maxim Razin
  • 9,114
  • 7
  • 34
  • 33
0

The only way to escape from being shown in the the process list is if you reimplement the entire functionality of the program you want to call in pure Bash functions. Function calls are not seperate processes. Usually this is not feasible, though.

Kilian Foth
  • 13,904
  • 5
  • 39
  • 57