I think the title to your question and the body of your question are contradicting each other a bit and I think that may be leading to some of the confusion with the other correct answers.
Your title says "Is it really safe" but in the body of your request you're comparing passing data via stdin vs command line arguments. When you compare two things the result of the comparison only speaks to the comparison and never allows you to make an absolute claim outside of the comparison itself. For example: The number 10 is more than the number 5. So 10 is "bigger" than 5. But is 10 a "big" number when there are obviously much bigger numbers? I can't justify saying "10 is a big number" just because it's bigger than some other number.
So: "is it safe?" is one question, but your question is really implying: "Is it safer?" with an emphasis on the extra "r" on "safer".
Just like it doesn't make sense to say that 10 is a big number when there are always bigger numbers: Nothing in information security is ever 100% "safe". As you point out there are attack vectors that could allow an attacker to get at data passed via stdin. The point is that there are FAR fewer attack vectors that allow an attacker to get access to data passed via stdin. AND those vectors are more difficult to achieve.
As the other answers point out: Data passed via command line arguments are visible for a long time. They are very often logged into log files as well as history files like .bash_history. These log files and history files can get backed up to the cloud, copied to other folders, disks, etc. This data is also visible to other system accounts which could potentially be compromised. In other words: An attacker has a lot of available attack vectors to gain access to command line argument data. And because of how long this data remains around for viewing, the attacker also has a larger window of time for which he can utilize to execute these attacks and still access the command line data.
With stdin there are not only fewer vectors: But the attacker also has a limited time window to execute a successful attack here. He has to compromise your account specifically, or root. Both of which are more difficult than compromising one of the system accounts. Then assuming he pulls off a successful attack to compromise your account or root: Now he can only see data being passed to stdin in real time. He can't go back and look in bash_history or log files to see data from stdin.
Between the lower number of attack vectors and the timing issue: It's obvious that passing data via stdin is SAFER. And that's what matters: It's not possible for something to be 100% foolproof/safe. Everything in security is about choosing the safest possible option which minimizes the number of attack vectors or exposed "surface area" of points that can potentially be attacked and lead to a system becoming compromised.
So: TL;DR: No, stdin is not 100% safe as nothing is. But it's far SAFER than command line arguments which is why it's preferred over using command line arguments to pass sensitive data like passwords.
pass=$(...)
filter by placing a file named:
in the CWD directory wheretr
runs. Remember to always quote args with meta characters.aaa
, while the colon would result in an empty password (assuming only alphabetics on stdin). Empty passwords in certain contexts mean no password required, e.g. for classic Unixpasswd
.