libssh: Fix CVE-2026-59846

libssh 0.10.6 predates the username-validation helper used by the
stable-0.11 fix, so the upstream commit in [1] cannot be applied as-is.
Adapt the same dangerous-character check directly at the ProxyCommand %r
expansion sink and add focused regression coverage.

The upstream advisory [2] identifies libssh 0.11.5 and 0.12.1 as the
fixed releases.

[1] https://gitlab.com/libssh/libssh-mirror/-/commit/56ce3c193eb06af5bf3b07ec0b4c7308b5c72130
[2] https://www.libssh.org/security/advisories/CVE-2026-59846.txt

Signed-off-by: Hetvi Thakar <hthakar@cisco.com>
Signed-off-by: Anuj Mittal <anuj.mittal@oss.qualcomm.com>
This commit is contained in:
Hetvi Thakar
2026-09-02 10:39:58 +05:30
committed by Anuj Mittal
parent 0428dc2fe2
commit df16e6650d
2 changed files with 88 additions and 0 deletions
@@ -0,0 +1,87 @@
From 19fe4c9fc7b3bd3553250bf9ddea03ed1dcf044f Mon Sep 17 00:00:00 2001
From: Jakub Jelen <jjelen@redhat.com>
Date: Thu, 2 Apr 2026 15:39:25 +0200
Subject: [PATCH] CVE-2026-59846 Block shell metacharacters from usernames
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When an attacker could sneak the dollar sign or backslash into the username
expanded for example in proxy command, it can result in printing environment
variables that might contain secrets.
This is a fixup of CVE-2023-6004 which fixed this for hostnames, but these
two metacharacters were left out from the username filter.
This keeps the list in one place to simplify maintenance.
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Pavol Žáčik <pzacik@redhat.com>
(cherry picked from commit 6309df220e3431deb41946f892f4bb5af8b59dba)
CVE: CVE-2026-59846
Upstream-Status: Backport [https://git.libssh.org/projects/libssh.git/commit/?id=56ce3c193eb06af5bf3b07ec0b4c7308b5c72130]
Backport Changes:
- libssh 0.10.6 predates ssh_check_username_syntax() and the centralized
SSH_DANGEROUS_SHELL_CHARS definition, so enforce the same character list
directly at the %r expansion sink in ssh_path_expand_escape().
- Add focused regression coverage to the existing path-expansion unit test
for dollar-sign, backslash, and command-separator usernames.
(cherry picked from commit 56ce3c193eb06af5bf3b07ec0b4c7308b5c72130)
Signed-off-by: Hetvi Thakar <hthakar@cisco.com>
---
src/misc.c | 9 +++++++++
tests/unittests/torture_misc.c | 18 ++++++++++++++++++
2 files changed, 27 insertions(+)
diff --git a/src/misc.c b/src/misc.c
index e78c92ba..15b427d7 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -1262,6 +1262,15 @@ char *ssh_path_expand_escape(ssh_session session, const char *s)
break;
case 'r':
if (session->opts.username) {
+ if (strpbrk(session->opts.username,
+ "'`\";&<>|(){}$\\,") != NULL) {
+ ssh_set_error(session,
+ SSH_FATAL,
+ "Invalid shell metacharacter in username");
+ free(buf);
+ free(r);
+ return NULL;
+ }
x = strdup(session->opts.username);
} else {
ssh_set_error(session, SSH_FATAL,
diff --git a/tests/unittests/torture_misc.c b/tests/unittests/torture_misc.c
index 82d6cf16..66d392ed 100644
--- a/tests/unittests/torture_misc.c
+++ b/tests/unittests/torture_misc.c
@@ -194,6 +194,24 @@ static void torture_path_expand_escape(void **state) {
assert_non_null(e);
assert_string_equal(e, "guru/meditation/222/by/root");
ssh_string_free_char(e);
+
+ free(session->opts.username);
+ session->opts.username = strdup("root$HOME");
+ assert_non_null(session->opts.username);
+ e = ssh_path_expand_escape(session, s);
+ assert_null(e);
+
+ free(session->opts.username);
+ session->opts.username = strdup("root\\user");
+ assert_non_null(session->opts.username);
+ e = ssh_path_expand_escape(session, s);
+ assert_null(e);
+
+ free(session->opts.username);
+ session->opts.username = strdup("root;id");
+ assert_non_null(session->opts.username);
+ e = ssh_path_expand_escape(session, s);
+ assert_null(e);
}
static void torture_path_expand_known_hosts(void **state) {
@@ -37,6 +37,7 @@ SRC_URI = "git://git.libssh.org/projects/libssh.git;protocol=https;branch=stable
file://CVE-2026-59847-02.patch \
file://CVE-2026-59843.patch \
file://CVE-2026-59844.patch \
file://CVE-2026-59846.patch \
"
SRCREV = "10e09e273f69e149389b3e0e5d44b8c221c2e7f6"