openssh-portable
openssh-portable copied to clipboard
command [argument ...] in ssh(1): a footgun
- The argument functionality in ssh is a common place of misuse, as it does not actually preserve the boundary. We should discourage people from using it.
- Manual is currently vague about what shell is used to run the passed command. Spell it out.
See, well, https://marc.info/?l=openssh-unix-dev&m=168509072920594&w=2.
Is it possible to fix this broken design by not squashing argv in the first place? sh -c allows arguments to be supplied so that they can be safely used as positional parameters within the command string without having to interpolate them as ssh requires.
Would it also be possible to just not wrap ForceCommand in sh -c at all?
Hmmmm.... let me check my old email link to see what I considered back then. Okay, I'm mostly back on track.
Regarding sh -c + positional: currently this stuff is called via https://github.com/openssh/openssh-portable/blob/3ad669f81aabbd2ba9fbd472903f680f598e1e99/session.c#L1709. I didn't consider positional arguments back then, but I still don't think it would work without making what currently works fail. ssh don't just use sh, it uses the user's preferred login shell. Adding positional arguments would add two requirements for the shell: [which currently does not need to be POSIX (it only needs to understand -c with a string)]
- it needs to accept extra arguments after the
-c blahblah, preferably with--between "blahblah" and the rest. - Just
sh -c 'blahblah' -- a b cdoesn't work; you got to reference the positional args likesh -c 'blahblah "$@" -- a b c, and that"$@"is going to narrow down the scope of support a lot.
Regarding ForceCommand: I am afraid not. The ForceCommand thing is probably (I didn't check) read from the config file as one big string, so it won't make sense to without a shell: execve wants a neat array of things.
I'm at least glad that someone's sharing my annoyance.
Checked the e-mail conversation again. The first reply from mirabilos mentioned that CAVEATS is more acceptable; I should do that once I sort out my other man page issues.
Oh yes, fixing this very, very old bug is going to break many uses of ssh.
When using -c with sh it is effectively taking the first argument as a command string (-c does not take a command string, it is a special mode) and the remaining as arguments starting from zero.
The problem openssh and others such as dropbear have is that they squash the command-line into a single string, obliterating any quoting information requiring people escape shell input in an attempt safely interpolate/inject arbitrary input.
I had hoped to workaround this by using ForceCommand but discovered that, for no reason, it wraps with sh -c anyway instead of passing it directly to exec(2) as a normal executable file.