Suppose I want to call a program that takes in a username and password to start. What are the risks with calling the program like ./prog --user 'User' --password 'Password' other than the obvious leak of a user looking over your shoulder?. Is there a safer way to pass in the password?

  • Which OS and from the desktop or from a VT? You're vulnerable to a lot of attacks if you have malware running on the same host. – Steve Dodier-Lazaro Oct 16 '14 at 23:17
  • Have a look the answers in this Q&A: stackoverflow.com/q/3830823/2805324. I found the memory overwrite one especially cunning. – LateralFractal Oct 17 '14 at 0:02

There's a few ways to pass the password to the program without typing it:

  1. Use read and a variable

    read -s password ; ./prog --user 'User' --password "$password"

    You will have to type the password before executing the program.

  2. Use redirection

    Put the password on password.txt and execute the program:

    ./prog --user 'User' --password `cat password.txt`

Note that even if those methods will conceal the password during the typing, anybody executing a ps xua | grep prog will be able to see the password anyway.

If you can change the program to read the password from stdin or reading a environment variable, it would make easier to conceal the password. In this case, those methods would work.

  • 3
    Using the environment is essentially just as bad as a command line argument (try ps aex on Linux for instance). – Mat Oct 17 '14 at 4:01
  • 2
    Both using a variable or substitution on the command line almost certainly expose it to other users via ps (and/or /proc), the shell expands them first. Try it and see: echo 60 > password.txt; sleep $(cat password.txt) & ps -fp $! – mr.spuratic Oct 17 '14 at 9:44

On most Unix systems the command line is visible to all users, via the ps command. This may not matter greatly if you're on a single-user system, but this is the reason that this approach is generally labelled as insecure. For example: MySQL manual.

A better alternative is to store the password in a file, which avoids this leak. You need to make sure the permissions on the file are appropriate. The link I provided explains how to do this for MySQL. A lot of other software support this in some way.

  • 3
    Re: "the command line is visible to all users": It's not the command line per se that's visible, but rather, the arguments to the program. For example, your answer makes it sound like you could store the password in a file named password_file and then write ./prog --user 'User' --password "$(cat password_file)"; but in fact, that would still have the same problem. – ruakh Oct 17 '14 at 6:00
  • 2
    See also openssl.org/docs/apps/openssl.html#PASS_PHRASE_ARGUMENTS for OpenSSL's take on this. – mr.spuratic Oct 17 '14 at 9:49

Make the program read the password itself.

You could use getpass(3) or similar if you are developing in a low-level language. For a shell script you can use read (as it is a builtin, there's no leaking in command arguments).

Also note that if you pass the credentials from somewhere else (such as running that command on a web server, filling the username and password from what was passed by a client), it needs proper quoting, so for instance a password of '`whoami`' doesn't result on remote code execution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.