Ssh – Bash: Checking if can sudo on remote host using sshpass; how ‘exposed’ is the password

bashnetworkingpasswordsshsudo

I am using bash script below to test whether sudo is available on a remote host.

I'm obtaining the password from user input. I understand (to a limited extent) that using passwords inside a script will involve security trade-offs, so I have a question about a particular aspect of this.

Please see script below, which uses sshpass and then tests if the user is able to run sudo --stdin --validate successfully.

To mitigate exposing the password (as best as I know?) I've opted to use sshpass with -e instead of -p, but just wondering about the second part—the echo \"${SSHPASS}\" | sudo --stdin --validate line.

After running this script and then looking through history on the remote host, I could not see the password 'echoed' on the command line both in the user account or as root.

So my question is: Does echoing like this at the remote end expose the password anywhere (and if so, where?), or is this method below "fairly safe"?

User environment on both ends is Ubuntu 18 or 20.

#!/bin/bash

# obtain username and host from user input
read -p "Enter username@host: " remote

# obtain password from user input
read -r -s -p "Enter password: " SSHPASS

# set password as environment variable for `sshpass` below, it requires this for `-e`
export SSHPASS

echo
echo -n "Testing if can sudo on ${remote}... "

if result=$( sshpass -e ssh -o PasswordAuthentication=yes "${remote}" "echo \"${SSHPASS}\" | sudo --stdin --validate" 2>&1 ); then
    echo "YES!"
else
    echo "FAILED"
    echo "${result}"
fi

unset SSHPASS

Best Answer

While it doesn't look like it, the password is actually exposed on the local and remote server.

The reason in both cases is that it is part of the command line of the processes, either sshpassor the more implicit bash -c as outlined below.

When you run a command via ssh <host> <command>, the command part is passed to the login shell via -c. This implies that any user that is able to list processes can see bash -c "echo "<password>" | sudo --stdin --validate".

If you want to test it out, a simple while ! ps aux | grep '[s]udo'; do :; done as any other user in the remote system should work. Note that this is an active wait loop and will spike CPU usage.

To fix that, you should echo the password and pipe it to your SSH instead of having it echoed remotely: echo "${SSHPASS}" | sshpass -e ssh -o PasswordAuthentication=yes "${remote}" "sudo --stdin --validate" 2>&1.