Shell – Passing Sensitive Data in Bash Using a Prompt

passwordSecurityshell

Suppose that I were using sha1pass to generate a hash of some sensitive password on the command line. I can use sha1pass mysecret to generate a hash of mysecret but this has the disadvantage that mysecret is now in the bash history. Is there a way to accomplish the end goal of this command while avoiding revealing mysecret in plain text, perhaps by using a passwd-style prompt?

I'm also interested in a generalized way to do this for passing sensitive data to any command. The method would change when the sensitive data is passed as an argument (such as in sha1pass) or on STDIN to some command.

Is there a way to accomplish this?


Edit: This question attracted a lot of attention and there have been several good answers offered below. A summary is:

  • As per @Kusalananda's answer, ideally one would never have to give a password or secret as a command-line argument to a utility. This is vulnerable in several ways as described by him, and one should use a better-designed utility that is capable of taking the secret input on STDIN
  • @vfbsilva's answer describes how to prevent things from being stored in bash history
  • @Jonathan's answer describes a perfectly good method for accomplishing this as long as the program can take its secret data on STDIN. As such, I've decided to accept this answer. sha1pass in my OP was just an example, but the discussion has established that better tools exist that do take data on STDIN.
  • as @R.. notes in his answer, use of command expansion on a variable is not safe.

So, in summary, I've accepted @Jonathan's answer since it's the best solution given that you have a well-designed and well-behaved program to work with.
Though passing a password or secret as a command-line argument is fundamentally unsafe, the other answers provide ways of mitigating the simple security concerns.

Best Answer

If using the zsh or bash shell, use the -s option to the read shell builtin to read a line from the terminal device without it echoing it.

IFS= read -rs VARIABLE < /dev/tty

Then you can use some fancy redirection to use the variable as stdin.

sha1pass <<<"$VARIABLE"

If anyone runs ps, all they'll see is "sha1pass".

That assumes that sha1pass reads the password from stdin (on one line, ignoring the line delimiter) when not given any argument.