oss-sec mailing list archives

Re: Announce: OpenSSH 10.1 released


From: David Leadbeater <dgl () dgl cx>
Date: Tue, 7 Oct 2025 17:04:44 +1100

On Mon, 6 Oct 2025 at 18:23, Damien Miller <djm () cvs openbsd org> 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\n () foo example com: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.

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

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

Attachment: ssh-cve-2025-61984.md
Description:


Current thread: