On Thu, Jun 29, 2023 at 11:33:15AM +0200, Sebastian Luhnburg wrote: > I want to use this password in an here document, which inject some > commands into a SSH-Connection (for simplification, I use the bash instead > of ssh in the test script below).
Skipping the "is it a bug or not" part, which has already been addressed as a mis-quoting issue, let's talk about the goal. First of all, is this the password *of* the ssh connection itself? If so, that can be addressed by switching to key-based authentication (and either using a key with no passphrase on it, or an ssh-agent to hold your passphrase). Second, are you trying to do something like this: ssh nonr...@some.host 'sudo some command' where the password is for "sudo" because you aren't logging in directly as root? The answer to this is so blastedly obvious that I shouldn't have to state it, but nonetheless, here we are: just ssh in as root instead of nonroot + sudo. Some folks will scream that this is a bad idea, horrible practice, can't do it, etc. These folks are idiots. Ssh can be configured to allow root logins only when using key authentication. That's as secure as you could ask for. Certainly it's at *least* as secure as throwing a password around and using sudo and invoking layers of quoting hell. But let's say it's not either of these things. Maybe it's a database access password or something, and you're actually doing something like: ssh nonr...@some.host 'mysql -p mydatabase ...' The obvious play here is to send the password on stdin. But you've introduced another layer of complication, because you're actually doing something like: ssh nonr...@some.host bash <<-EOF some command another command mysql -p"$injected_password" mydatabase EOF where stdin is already tied up sending the script for bash to execute, and therefore can't be used to send the database password. This is NOT going to work. What you want to do instead is pass the password as an *argument* to bash -s. You've already got the @Q (or printf %q) part, which is a necessary step. You just need the rest of it. ssh nonr...@some.host bash -s "${password@Q}" <<-'EOF' some command another command mysql -p"$1" mydatabase EOF This is also described in a bit more detail at <https://mywiki.wooledge.org/BashProgramming/05#Passing_arguments_to_ssh>. I recommend reading that whole page when you get a chance. Here it is in action: unicorn:~$ password='$foo&bar' unicorn:~$ ssh localhost bash -s "${password@Q}" <<-'EOF' > printf 'Password is <%s>\n' "$1" > EOF greg@localhost's password: Password is <$foo&bar>