On 10/7/25 02:04, David Leadbeater wrote:
> On Mon, 6 Oct 2025 at 18:23, Damien Miller <[email protected]> wrote:
> [...]
>> Security
>> ========
>>
>> * ssh(1): disallow control characters in usernames passed via the
>>   commandline or expanded using %-sequences from the configuration
>>   file, and disallow \0 characters in ssh:// URIs.
>>
>>   If an ssh(1) commandline was constructed using usernames or URIs
>>   obtained from an untrusted source, and if a ProxyCommand that uses
>>   the %u expansion was configured, then it may be possible for an
>>   attacker to inject shell expressions that may be executed when the
>>   proxy command is started.
>>
>>   We strongly recommend against using untrusted inputs to construct
>>   ssh(1) commandlines.
>>
>>   This change also relaxes the validity checks in one small way:
>>   usernames supplied via the configuration file as literals (i.e.
>>   that have no % expansion characters) are not subject to these
>>   validity checks. This allows usernames that contain arbitrary
>>   characters to be used, but only via configuration files. This is
>>   done on the basis that ssh's configuration is trusted.
>>
>>   This issue was reported by David Leadbeater.
> 
> There was a minor error in the above, it should say %r (remote
> username), not %u (local username).
> 
> It has also now been assigned CVE-2025-61984.
> 
> I thought it was worth expanding on this issue, it is essentially a
> follow up from CVE-2023-51385, where if a user clones a git repo or
> otherwise performs another action that passes an attacker controlled
> string to SSH, it could be passed through to the user configured
> ProxyCommand. i.e. it needs both a user action and a particular user
> configuration.
> 
> The ProxyCommand is run through "exec %s" passed to the user's $SHELL.
> One may think that given it is "exec" that it's not possible to run
> another command after it, but bash will ignore the line if it fails
> for certain syntax errors, and it is possible to pass something like:
> "$[+]", an invalid arithmetical expression.
> 
> The proof of concept is therefore a Git repo with a submodule (in
> .gitmodules) like so:
> 
> [submodule "foo"]
>         path = foo
>         url = "$[+]\nsource poc.sh\[email protected]:foo"
> 
> Combined with a ~/.ssh/config configured with something like this:
> 
> Host *.example.com
>         ProxyCommand some-command %r@%h:%p
> 
> Then on cloning the git repo with "git clone --recursive" the "poc.sh"
> in it will be sourced.

Would it make sense to only allow ASCII characters that are not special
to the shell?  I think Git should enforce this restriction, as such
usernames are very risky and unlikely in legitimate use-cases.  OpenSSH
enforcing this would be even better.

> It is also worth pointing out that a mitigation (and defence for
> future similar issues) is to stop git from cloning repositories over
> SSH for submodules, this can be done with:
> 
>    git config --global protocol.ssh.allow user

This should be the default, as SSH is authenticated and the clone could
have CSRF-like side-effects.

> There are some potential other vectors than git, so that is not a
> complete mitigation, but git is one of the most common vectors and
> this configuration option follows the advice in the release notes of
> not "using untrusted inputs to construct ssh(1) commandlines".
> 
> I've put a more complete write up at
> https://dgl.cx/2025/10/bash-a-newline-ssh-proxycommand-cve-2025-61984
> (attached here in markdown for the archives). In particular I think
> this shell behaviour is quite interesting and may be worth looking out
> for in other tools.
> 
> David

Would it make sense to provide an option to quote shell metacharacters
when expanding, or to simply forbid them outright?  The latter would be
a complete solution.
-- 
Sincerely,
Demi Marie Obenour (she/her/hers)

Attachment: OpenPGP_0xB288B55FFF9C22C1.asc
Description: OpenPGP public key

Attachment: OpenPGP_signature.asc
Description: OpenPGP digital signature

Reply via email to