Mailing List Archive

command [argument ...] in ssh(1): a footgun
Hi,

ssh(1) currently affords an argument-passing functionality, but as the
manpage states, all arguments are simply concatenated by space. This
behavior is non-obvious for those reading only the synopsis: one would
expect something that takes argv input to somehow preserve the argument
boundary and not, say, let a semicolon ruin all the fun. This is
probably old news for all of you.

I have two proposals for dealing with this problem. One modest, one less
so.

The modest proposal is that we put a giant CAVEATS section in the manual
page. Now this does not help anyone who won't read the manpage at all,
but at least by spelling it out we catch skim readers' attention. If
someone's code blows up with this assumption, we can at least say "we
told you so".

The less modest one is we throw out the "[argument ...]" part
altogether. It does not add much functionality, really: everything it
does can be achieved by putting a big quotation mark over the existing
arguments invocation. There is not much to lose by doing so, except for
the logistical costs of deprecation and removal.

What about escaping the arguments? Nobody said the user has to use a
POSIX shell, so we simply don't have a universal escape method. The
manual's DESCRIPTION section is a bit vague here: it does not specify
which shell is used. In truth, session.c runs the user's shell via the
`-c` option, not just the system POSIX shell via system().

Sincerely,
Mingye Wang (Artoria2e5)

_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: command [argument ...] in ssh(1): a footgun [ In reply to ]
On Fri, 26 May 2023, Mingye Wang (Artoria2e5) wrote:

> ssh(1) currently affords an argument-passing functionality, but as the manpage
> states, all arguments are simply concatenated by space.

How else would it do that? The arguments are processed by the
shell first then passed as an array of NUL-terminated strings.

> The modest proposal is that we put a giant CAVEATS section in the manual page.

That might be useful indeed.

> The less modest one is we throw out the "[argument ...]" part altogether. It

Absolutely not. This will break about all uses of ssh in existence.

> What about escaping the arguments? Nobody said the user has to use a POSIX

Absolutely not. This will break almost all uses of ssh in existence.

bye,
//mirabilos
--
Infrastrukturexperte • tarent solutions GmbH
Am Dickobskreuz 10, D-53121 Bonn • http://www.tarent.de/
Telephon +49 228 54881-393 • Fax: +49 228 54881-235
HRB AG Bonn 5168 • USt-ID (VAT): DE122264941
Geschäftsführer: Dr. Stefan Barth, Kai Ebenrett, Boris Esser, Alexander Steeg

****************************************************
/?\ The UTF-8 Ribbon
? ? Campaign against Mit dem tarent-Newsletter nichts mehr verpassen:
 ?  HTML eMail! Also, https://www.tarent.de/newsletter
? ? header encryption!
****************************************************
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: command [argument ...] in ssh(1): a footgun [ In reply to ]
On Sat, May 27, 2023 at 12:08:43AM +0200, Thorsten Glaser <t.glaser@tarent.de> wrote:

> On Fri, 26 May 2023, Mingye Wang (Artoria2e5) wrote:
>
> > ssh(1) currently affords an argument-passing functionality, but as the manpage
> > states, all arguments are simply concatenated by space.
>
> How else would it do that? The arguments are processed by the
> shell first then passed as an array of NUL-terminated strings.
>
> > The modest proposal is that we put a giant CAVEATS section in the manual page.
>
> That might be useful indeed.

I think that stating "all arguments are simply
concatenated by space" is arguably clear enough, but it
can be good to elaborate on even obvious implications.
It can save time, especially with an example.

So, perhaps this could be added to the existing
sentence/paragraph:

"so any spaces in individual arguments must be
quoted using the syntax of the destination
user's login shell".

If an example were needed, something like these should
make it clear:

ssh user@host ls -l "'a b'"
ssh user@host "ls -l a\ b"
ssh user@host "ls -l 'a b'"

Putting the extra information in a separate CAVEAT
section is less helpful. I think it's better to put it
where the feature itself is documented. People looking
just for the documentation on that feature probably
won't see the CAVEAT section at all.

> > The less modest one is we throw out the "[argument ...]" part altogether. It
>
> Absolutely not. This will break about all uses of ssh in existence.
>
> > What about escaping the arguments? Nobody said the user has to use a POSIX
>
> Absolutely not. This will break almost all uses of ssh in existence.

Not knowing the details of each user's login shell is
precisely the reason that ssh couldn't ever do the
quoting itself. Each shell is its own language with
conceivably different quoting notation. The user knows
what that language is because it's the shell they chose
to use. ssh doesn't. It only knows the path to the
login shell executable, and it hands the command over
to the login shell to parse and execute. ssh is smart
enough not to try to interpret the command itself in
any way. Any attempt to do so would limit ssh's ability
to execute arbitrary commands to only those that it can
interpret. So the user has to do the quoting themselves.

cheers,
raf

> bye,
> //mirabilos
> --
> Infrastrukturexperte • tarent solutions GmbH
> Am Dickobskreuz 10, D-53121 Bonn • http://www.tarent.de/
> Telephon +49 228 54881-393 • Fax: +49 228 54881-235
> HRB AG Bonn 5168 • USt-ID (VAT): DE122264941
> Geschäftsführer: Dr. Stefan Barth, Kai Ebenrett, Boris Esser, Alexander Steeg
>
> ****************************************************
> /?\ The UTF-8 Ribbon
> ? ? Campaign against Mit dem tarent-Newsletter nichts mehr verpassen:
>  ?  HTML eMail! Also, https://www.tarent.de/newsletter
> ? ? header encryption!
> ****************************************************
> _______________________________________________
> openssh-unix-dev mailing list
> openssh-unix-dev@mindrot.org
> https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: command [argument ...] in ssh(1): a footgun [ In reply to ]
On Sat, 27 May 2023, raf wrote:

>So, perhaps this could be added to the existing
>sentence/paragraph:
>
> "so any spaces in individual arguments must be

Must they? No, a single space will do just fine.

> quoted using the syntax of the destination
> user's login shell".
… keeping in mind the source shell’s quoting as well.

>If an example were needed, something like these should
>make it clear:
>
> ssh user@host ls -l "'a b'"
> ssh user@host "ls -l a\ b"

This one, incidentally, sends 'ls -l a b' to the remote shell.
ssh user@host "ls -l a\\ b"
has the effect you want; the first backslash is eaten by the
local shell.

> ssh user@host "ls -l 'a b'"

But you could also just do:
ssh user@host ls -l \'a b\'

Only if it’s more than one space, or different whitespace,
does this come into effect.

The more important point is things like pipes and redirections anyway.

>Putting the extra information in a separate CAVEAT
>section is less helpful. I think it's better to put it
>where the feature itself is documented. People looking

Perhaps, perhaps not. Too much information in one place might have
the opposite effect. I’d rather give a short line there, with a
reference to .Sx CAVEATS below.

>Not knowing the details of each user's login shell is
>precisely the reason that ssh couldn't ever do the

Yes, exactly.

But for…
ssh remhost ls -l \>foo

… it MUST NOT quote the I/O redirection sign, otherwise
the redirection would not work. That’s why I’m saying it
needs not and must not quote.

bye,
//mirabilos (current developer of a POSIX-compatible shell)
--
Infrastrukturexperte • tarent solutions GmbH
Am Dickobskreuz 10, D-53121 Bonn • http://www.tarent.de/
Telephon +49 228 54881-393 • Fax: +49 228 54881-235
HRB AG Bonn 5168 • USt-ID (VAT): DE122264941
Geschäftsführer: Dr. Stefan Barth, Kai Ebenrett, Boris Esser, Alexander Steeg

****************************************************
/?\ The UTF-8 Ribbon
? ? Campaign against Mit dem tarent-Newsletter nichts mehr verpassen:
 ?  HTML eMail! Also, https://www.tarent.de/newsletter
? ? header encryption!
****************************************************
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: command [argument ...] in ssh(1): a footgun [ In reply to ]
On 27/05/2023 01:45, Thorsten Glaser wrote:
>> ssh user@host "ls -l a\ b"
> This one, incidentally, sends 'ls -l a b' to the remote shell.
> ssh user@host "ls -l a\\ b"
> has the effect you want; the first backslash is eaten by the
> local shell.
>
Or is it?

$ echo "ls -l a\ b"
ls -l a\ b
$

This is with bash 5.2.15. From the man page:

       Enclosing characters in double quotes preserves the literal  value
       of  all  characters within the quotes, with the exception of $, `,
       \, and, when history expansion is enabled, !.
...
       The backslash
       retains its special meaning only when followed by one of the  fol-
       lowing  characters:  $, `, ", \, or <newline>.

Other shells may be different, of course.

Regards,

Brian.
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: command [argument ...] in ssh(1): a footgun [ In reply to ]
On Sat, 27 May 2023, Brian Candler wrote:

>> has the effect you want; the first backslash is eaten by the
>> local shell.
>>
> Or is it?
>
> $ echo "ls -l a\ b"
> ls -l a\ b

Ah oops, in POSIX only when followed by [$`"\\\n] of course.
I’m not fond of “loose” backslashes though.

That does not detract from the point, ofc.

> Other shells may be different, of course.

That they do. (Same for echo: that may *also* eat that backslash.
For echo, basically, if the first argument begins with a hyphen-minus
or any argument contains a backslash, its use is not portable.)

bye,
//mirabilos
--
Infrastrukturexperte • tarent solutions GmbH
Am Dickobskreuz 10, D-53121 Bonn • http://www.tarent.de/
Telephon +49 228 54881-393 • Fax: +49 228 54881-235
HRB AG Bonn 5168 • USt-ID (VAT): DE122264941
Geschäftsführer: Dr. Stefan Barth, Kai Ebenrett, Boris Esser, Alexander Steeg

****************************************************
/?\ The UTF-8 Ribbon
? ? Campaign against Mit dem tarent-Newsletter nichts mehr verpassen:
 ?  HTML eMail! Also, https://www.tarent.de/newsletter
? ? header encryption!
****************************************************
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: command [argument ...] in ssh(1): a footgun [ In reply to ]
On Sat, May 27, 2023 at 02:45:34AM +0200, Thorsten Glaser <t.glaser@tarent.de> wrote:

> On Sat, 27 May 2023, raf wrote:
>
> >So, perhaps this could be added to the existing
> >sentence/paragraph:
> >
> > "so any spaces in individual arguments must be
>
> Must they? No, a single space will do just fine.

They do if you want the receiving shell to not interpret
the space as a separator between arguments.

> > quoted using the syntax of the destination
> > user's login shell".
> … keeping in mind the source shell’s quoting as well.
>
> >If an example were needed, something like these should
> >make it clear:
> >
> > ssh user@host ls -l "'a b'"
> > ssh user@host "ls -l a\ b"
>
> This one, incidentally, sends 'ls -l a b' to the remote shell.
> ssh user@host "ls -l a\\ b"
> has the effect you want; the first backslash is eaten by the
> local shell.

Perhaps that depends on the local shell. It works with zsh.
Testing with dash would probably be better. That works too.
I think you might be wrong. I think the slash would only
be eaten by the local shell if it weren't inside doublequotes.

> > ssh user@host "ls -l 'a b'"
>
> But you could also just do:
> ssh user@host ls -l \'a b\'
>
> Only if it’s more than one space, or different whitespace,
> does this come into effect.

That wasn't one of my examples. That wouldn't work for
a file "a b", as you say.

> The more important point is things like pipes and redirections anyway.

For them, the entire command needs to be quoted.

> >Putting the extra information in a separate CAVEAT
> >section is less helpful. I think it's better to put it
> >where the feature itself is documented. People looking
>
> Perhaps, perhaps not. Too much information in one place might have
> the opposite effect. I’d rather give a short line there, with a
> reference to .Sx CAVEATS below.

Yes, as long as it explicitly refers the reader to CAVEAT.

> >Not knowing the details of each user's login shell is
> >precisely the reason that ssh couldn't ever do the
>
> Yes, exactly.
>
> But for…
> ssh remhost ls -l \>foo
>
> … it MUST NOT quote the I/O redirection sign, otherwise
> the redirection would not work. That’s why I’m saying it
> needs not and must not quote.

The redirecton sign isn't a space. We're talking about spaces.
But the redirection does have to "quoted" locally otherwise
it would apply to the local process, but it would need to
be quoted like this:

ssh remhost "ls -l >foo"

> bye,
> //mirabilos (current developer of a POSIX-compatible shell)
> --
> Infrastrukturexperte • tarent solutions GmbH
> Am Dickobskreuz 10, D-53121 Bonn • http://www.tarent.de/
> Telephon +49 228 54881-393 • Fax: +49 228 54881-235
> HRB AG Bonn 5168 • USt-ID (VAT): DE122264941
> Geschäftsführer: Dr. Stefan Barth, Kai Ebenrett, Boris Esser, Alexander Steeg
>
> ****************************************************
> /?\ The UTF-8 Ribbon
> ? ? Campaign against Mit dem tarent-Newsletter nichts mehr verpassen:
>  ?  HTML eMail! Also, https://www.tarent.de/newsletter
> ? ? header encryption!
> ****************************************************
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: command [argument ...] in ssh(1): a footgun [ In reply to ]
On Sun, 28 May 2023, raf wrote:

>> > "so any spaces in individual arguments must be
>>
>> Must they? No, a single space will do just fine.
>
>They do if you want the receiving shell to not interpret
>the space as a separator between arguments.

Nope.

tg@caas:~ $ echo foo >'a b'
tg@caas:~ $ ^D
Connection to caas[…] closed.

$ ssh caas cat \'a \ b\'
foo

Nothing special about explicit space vs. implicit space by
argument separator here. On the recipient side, the entire
argument vector is just space-joined into one string then
passed to the (remote)local shell. Where the space comes
from is irrelevant.

>> has the effect you want; the first backslash is eaten by the
>> local shell.
>
>Perhaps that depends on the local shell.

Yes, I had a different one in mind with this, see the other mail.
POSIX does guarantee this (even though it still “feels wrong” to
me).

>That wasn't one of my examples. That wouldn't work for
>a file "a b", as you say.

See above. For "a b" you could use \'a \ b\'.

>> the opposite effect. I’d rather give a short line there, with a
>> reference to .Sx CAVEATS below.
>
>Yes, as long as it explicitly refers the reader to CAVEAT.

That’s what .Sx does, though such an explicit reference is
only appropriate in the most dire cases. (Given what I’ve
seen able shell quoting, this does count.)

bye,
//mirabilos
--
Infrastrukturexperte • tarent solutions GmbH
Am Dickobskreuz 10, D-53121 Bonn • http://www.tarent.de/
Telephon +49 228 54881-393 • Fax: +49 228 54881-235
HRB AG Bonn 5168 • USt-ID (VAT): DE122264941
Geschäftsführer: Dr. Stefan Barth, Kai Ebenrett, Boris Esser, Alexander Steeg

****************************************************
/?\ The UTF-8 Ribbon
? ? Campaign against Mit dem tarent-Newsletter nichts mehr verpassen:
 ?  HTML eMail! Also, https://www.tarent.de/newsletter
? ? header encryption!
****************************************************
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: command [argument ...] in ssh(1): a footgun [ In reply to ]
raf wrote:
> Not knowing the details of each user's login shell is
> precisely the reason that ssh couldn't ever do the
> quoting itself.

The footgun is unrelated to shells.

The SSH_MSG_CHANNEL_REQUEST protocol message for "exec" (RFC 4254)
channels which are used to run a single remote command contains
exactly one string for the command.

sshd (see bottom of do_child() in session.c) runs that command string as:

remote_users_shell -c command


//Peter
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: command [argument ...] in ssh(1): a footgun [ In reply to ]
On Mon, May 29, 2023 at 06:35:34PM +0000, Peter Stuge <peter@stuge.se> wrote:

> raf wrote:
> > Not knowing the details of each user's login shell is
> > precisely the reason that ssh couldn't ever do the
> > quoting itself.
>
> The footgun is unrelated to shells.
>
> The SSH_MSG_CHANNEL_REQUEST protocol message for "exec" (RFC 4254)
> channels which are used to run a single remote command contains
> exactly one string for the command.
>
> sshd (see bottom of do_child() in session.c) runs that command string as:
>
> remote_users_shell -c command

I'm aware of that. That's why I said what I said.
Sorry, but I don't understand what point you are making.

> //Peter
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: command [argument ...] in ssh(1): a footgun [ In reply to ]
On 27.05.23 00:08, Thorsten Glaser wrote:
> On Fri, 26 May 2023, Mingye Wang (Artoria2e5) wrote:
>> The less modest one is we throw out the "[argument ...]" part altogether. It
>
> Absolutely not. This will break about all uses of ssh in existence.

You are confusing "ssh(1) does (not) distinguish between 'command' and
'argument(s)'" with "the 'command' may (not) be understood by the remote
shell as having arguments". To ssh(1), as it currently stands, "command"
is meant to be opaque, and omitting "[argument ...]" from the ssh(!)
manpage would indicate just that. For all we know, the remote shell
could break the command into parts at underscores, rather than whitespace.

Let's summarize the general situation, though:
-- We cannot reduce the local shell's influence re: quoting to zero as
that's what the (interactive) user uses to input the (remote) command
in the first place. (Ignoring the possibility of RemoteCommand in a
(pseudo?) config file for the moment.)
-- We cannot reduce the remote shell's influence to zero as long as
sshd(8) uses that to execute the command.
-- If we avoid that and execv() the command directly, we make the UI
disparate from what the user experiences with an interactive login
(shell aliases, env vars, ...).
Pick your poison ...

It could be argued that ssh(1) already offers a certain amount of
*choices* influencing the remote shell (login shell or not, tty or not,
both usually affecting the dotfiles the remote shell will load), so I
*could* see a "switch to remote direct execv()" *option* on the (far)
horizon, but not a change of the default behavior.

(Another *technical* possibility would be to use some sort of encoding
on the command transmitted from ssh to sshd, and thus make that a fully
transparent bit stream that can carry NULs into a hypothetical remote
"shell" that can detect and interpret them, but that would still require
a protocol extension and I'm not sure how the part of providing such as
an input through the local shell could be made anything but a pain in
the forefingers ...)

From the point of terminology, taking the respective shells out of the
equation makes the entire thing less of a "secure shell" or "remote
login" and more like an RPC or distributed queueing system ...

Regards,
--
Jochen Bern
Systemingenieur

Binect GmbH
Re: command [argument ...] in ssh(1): a footgun [ In reply to ]
On Tue, 30 May 2023, Jochen Bern wrote:

> -- We cannot reduce the local shell's influence re: quoting to zero as

My point here is that I absolutely *want* the remote shell’s
influence because it’s otherwise not possible to do many of
the things we currently can do.

bye,
//mirabilos
--
Infrastrukturexperte • tarent solutions GmbH
Am Dickobskreuz 10, D-53121 Bonn • http://www.tarent.de/
Telephon +49 228 54881-393 • Fax: +49 228 54881-235
HRB AG Bonn 5168 • USt-ID (VAT): DE122264941
Geschäftsführer: Dr. Stefan Barth, Kai Ebenrett, Boris Esser, Alexander Steeg

****************************************************
/?\ The UTF-8 Ribbon
? ? Campaign against Mit dem tarent-Newsletter nichts mehr verpassen:
 ?  HTML eMail! Also, https://www.tarent.de/newsletter
? ? header encryption!
****************************************************
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: command [argument ...] in ssh(1): a footgun [ In reply to ]
raf wrote:
> > > Not knowing the details of each user's login shell is
> > > precisely the reason that ssh couldn't ever do the
> > > quoting itself.
> >
> > The footgun is unrelated to shells.
> >
> > The SSH_MSG_CHANNEL_REQUEST protocol message for "exec" (RFC 4254)
> > channels which are used to run a single remote command contains
> > exactly one string for the command.
> >
> > sshd (see bottom of do_child() in session.c) runs that command string as:
> >
> > remote_users_shell -c command
>
> I'm aware of that. That's why I said what I said.
> Sorry, but I don't understand what point you are making.

My point wasn't directed at you specifically, rather at the thread in general.


Jochen Bern wrote:
> Let's summarize the general situation, though:
> -- We cannot reduce the local shell's influence re: quoting to zero

This happens before the ssh client process starts.


> -- We cannot reduce the remote shell's influence to zero as long as
> sshd(8) uses that to execute the command.

As I pointed out sshd always uses the shell. (Bottom of session.c:do_child())


> -- If we avoid that and execv() the command directly,

The protocol transfers a single command string to the server. The
server has no array to pass to execv().


> I *could* see a "switch to remote direct execv()" *option* on the (far)
> horizon, but not a change of the default behavior.

I tried to make clear that the protocol does not allow such an option.


> use some sort of encoding on the command transmitted from ssh to sshd

The protocol message is binary transparent; it's certainly possible
to serialize a data structure into the command string and use a shell
on the server that deserializes its -c argument. Seems convoluted though.


//Peter
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: command [argument ...] in ssh(1): a footgun [ In reply to ]
On Tue, May 30, 2023 at 05:02:21PM +0000, Peter Stuge <peter@stuge.se> wrote:

> raf wrote:
> > > > Not knowing the details of each user's login shell is
> > > > precisely the reason that ssh couldn't ever do the
> > > > quoting itself.
> > >
> > > The footgun is unrelated to shells.
> > >
> > > The SSH_MSG_CHANNEL_REQUEST protocol message for "exec" (RFC 4254)
> > > channels which are used to run a single remote command contains
> > > exactly one string for the command.
> > >
> > > sshd (see bottom of do_child() in session.c) runs that command string as:
> > >
> > > remote_users_shell -c command
> >
> > I'm aware of that. That's why I said what I said.
> > Sorry, but I don't understand what point you are making.
>
> My point wasn't directed at you specifically, rather at the thread in general.
>
>
> Jochen Bern wrote:
> > Let's summarize the general situation, though:
> > -- We cannot reduce the local shell's influence re: quoting to zero
>
> This happens before the ssh client process starts.
>
>
> > -- We cannot reduce the remote shell's influence to zero as long as
> > sshd(8) uses that to execute the command.
>
> As I pointed out sshd always uses the shell. (Bottom of session.c:do_child())
>
>
> > -- If we avoid that and execv() the command directly,
>
> The protocol transfers a single command string to the server. The
> server has no array to pass to execv().

Nor should it. That would infantalize ssh. It would
mean that shell globbing and pipelines and for loops
would stop working, along with all the rest of its
syntax (whatever that might be), without requiring the
user to type in sh -c "'...'" themselves. I think the
existing method is great. It supports everything that
the remote shell is capable of, whatever that remote
shell might happen to be.

The only problem (it seems) is that not everyone
realises that they might sometimes need to include
quoting of some kind in the local ssh command that
needs to make it to the remote command where it is
executed. Although that should quickly become apparent
to anyone who needs to know it (like the first time you
realise that the globbing needs to happen at the remote
end). This can be fixed with a documentation change to
better prepare user expectations, not with a code
change to make ssh less capable. I'm not saying that a
documentation change is necessary, only that it would
be sufficient.

If examples are too verbose, perhaps the manual could
just add a mention of the fact that the resulting
command (where it mentions that local arguments are
joined with a space) is executed remotely by passing it
to the remote user's login shell as its -c option
argument. That could be a short addition that might do
the trick for preparing user expectations. Personally,
I don't think even that is needed, but my opinion isn't
important. And it wouldn't hurt.

Actually, I'm trying to find the mention in the manpage
that started this and can't find it. It doesn't mention
[arguments...] after [command] like I think the OP
asked to have removed. I must be misremembering. The
synopsis ends with: "[command]". And the DESCRIPTION
section (paragraph 3) says:

If a command is specified, it is executed on the
remote host instead of a login shell.

I can't see where it says that arguments are joined
with a space. Maybe I'm reading it wrong.

Later (AUTHENTICATION section) it says:

When the user's identity has been accepted by the
server, the server either executes the given
command in a non-interactive session or, if no
command has been specified, logs into the machine
and gives the user a normal shell as an interactive
session. All communication with the remote command
or shell will be automatically encrypted.

Perhaps this could be added after that paragraph:

If a command has been specified, it is executed by
passing it to the remote user's login shell as the
argument to its -c option (e.g., sh -c '...'). If
multiple command line arguments are specified, they
are first concatenated, with a space between each, to
form a single argument for the -c option. Note that
there are cases where extra quoting is needed for the
command to be interpreted as intended by the remote
shell.

That tells the user which shell is used, and it tells
how it is executed, so the user knows to read about the
-c option in their own shell's documentation if
necessary, and it points out the fact that the user
needs to realise that the command is being specified
and interpreted in a local shell, to be interpreted
again by a remote shell, so they need to take the
combination of local and remote shell syntax into
consideration.

> > I *could* see a "switch to remote direct execv()" *option* on the (far)
> > horizon, but not a change of the default behavior.
>
> I tried to make clear that the protocol does not allow such an option.
>
>
> > use some sort of encoding on the command transmitted from ssh to sshd
>
> The protocol message is binary transparent; it's certainly possible
> to serialize a data structure into the command string and use a shell
> on the server that deserializes its -c argument. Seems convoluted though.

None of that sounds (to me) like it would serve a
useful purpose anyway.

> //Peter

cheers,
raf

_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: command [argument ...] in ssh(1): a footgun [ In reply to ]
On 31/05/2023 05:14, raf wrote:
> Actually, I'm trying to find the mention in the manpage
> that started this and can't find it. It doesn't mention
> [arguments...] after [command] like I think the OP
> asked to have removed. I must be misremembering. The
> synopsis ends with: "[command]". And the DESCRIPTION
> section (paragraph 3) says:
>
> If a command is specified, it is executed on the
> remote host instead of a login shell.
>
> I can't see where it says that arguments are joined
> with a space. Maybe I'm reading it wrong.

I'm on macOS with ssh installed from homebrew.

$ ssh -V
OpenSSH_9.2p1, OpenSSL 1.1.1t  7 Feb 2023

"man ssh" starts as follows:

SSH(1)                            General Commands
Manual                           SSH(1)

NAME
     ssh – OpenSSH remote login client

SYNOPSIS
     ssh [-46AaCfGgKkMNnqsTtVvXxYy] [-B bind_interface] [-b
bind_address] [-c cipher_spec]
         [-D [bind_address:]port] [-E log_file] [-e escape_char] [-F
configfile]
         [-I pkcs11] [-i identity_file] [-J destination] [-L address]
[-l login_name]
         [-m mac_spec] [-O ctl_cmd] [-o option] [-p port] [-Q
query_option] [-R address]
         [-S ctl_path] [-W host:port] [-w local_tun[:remote_tun]]
destination
*[command [argument ...]]*

DESCRIPTION
     ssh (SSH client) is a program for logging into a remote machine
and for executing
     commands on a remote machine.  It is intended to provide secure
encrypted
     communications between two untrusted hosts over an insecure
network.  X11
     connections, arbitrary TCP ports and UNIX-domain sockets can also
be forwarded over
     the secure channel.

     ssh connects and logs into the specified destination, which may be
specified as
     either [user@]hostname or a URI of the form
ssh://[user@]hostname[:port].  The user
     must prove their identity to the remote machine using one of
several methods (see
     below).

     If a command is specified, it will be executed on the remote host
instead of a login
     shell. *A complete command line may be specified as command, or it
may have**
**     additional arguments.  If supplied, the arguments will be
appended to the command,**
**     separated by spaces, before it is sent to the server to be executed.*

...

This agrees with
https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/ssh.1?rev=1.433&content-type=text/x-cvsweb-markup

_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: command [argument ...] in ssh(1): a footgun [ In reply to ]
On Wed, May 31, 2023 at 07:46:49AM +0100, Brian Candler <b.candler@pobox.com> wrote:

> On 31/05/2023 05:14, raf wrote:
> > Actually, I'm trying to find the mention in the manpage
> > that started this and can't find it. It doesn't mention
> > [arguments...] after [command] like I think the OP
> > asked to have removed. I must be misremembering. The
> > synopsis ends with: "[command]". And the DESCRIPTION
> > section (paragraph 3) says:
> >
> > If a command is specified, it is executed on the
> > remote host instead of a login shell.
> >
> > I can't see where it says that arguments are joined
> > with a space. Maybe I'm reading it wrong.
>
> I'm on macOS with ssh installed from homebrew.
>
> $ ssh -V
> OpenSSH_9.2p1, OpenSSL 1.1.1t  7 Feb 2023
>
> "man ssh" starts as follows:
>
> SSH(1)                            General Commands
> Manual                           SSH(1)
>
> NAME
>      ssh – OpenSSH remote login client
>
> SYNOPSIS
>      ssh [-46AaCfGgKkMNnqsTtVvXxYy] [-B bind_interface] [-b bind_address]
> [-c cipher_spec]
>          [-D [bind_address:]port] [-E log_file] [-e escape_char] [-F
> configfile]
>          [-I pkcs11] [-i identity_file] [-J destination] [-L address] [-l
> login_name]
>          [-m mac_spec] [-O ctl_cmd] [-o option] [-p port] [-Q query_option]
> [-R address]
>          [-S ctl_path] [-W host:port] [-w local_tun[:remote_tun]]
> destination
> *[command [argument ...]]*

Thanks. I was reading it on debian stable:

SSH(1) BSD General Commands Manual SSH(1)

NAME
ssh — OpenSSH remote login client

SYNOPSIS
ssh [-46AaCfGgKkMN......address] [-c cipher_spec] [-D [bind_address:]port]
[-E log_file] ......1] [-i identity_file] [-J destination] [-L address]
[-l login_name......-p port] [-Q query_option] [-R address]
[-S ctl_path] ...... destination [command]

It's an older version:

OpenSSH_8.4p1 Debian-5+deb11u1, OpenSSL 1.1.1n 15 Mar 2022

cheers,
raf

_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev