aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEd Maste <emaste@FreeBSD.org>2024-01-05 18:12:09 +0000
committerEd Maste <emaste@FreeBSD.org>2024-01-08 04:21:51 +0000
commitb8d5f0482d43a6a5dca6eb07a98c806d476e8cd9 (patch)
tree0c1c7a979443c6725658aebd59b8cf3bd30a10e5
parent221a6bc397ad8a8400c3b4cb6e020cba56f0d68f (diff)
downloadsrc-b8d5f0482d43a6a5dca6eb07a98c806d476e8cd9.tar.gz
src-b8d5f0482d43a6a5dca6eb07a98c806d476e8cd9.zip
ssh: ban user/hostnames with most shell metacharacters
Cherry-picked from OpenSSH commit 7ef3787c84b6: This makes ssh(1) refuse user or host names provided on the commandline that contain most shell metacharacters. Some programs that invoke ssh(1) using untrusted data do not filter metacharacters in arguments they supply. This could create interactions with user-specified ProxyCommand and other directives that allow shell injection attacks to occur. It's a mistake to invoke ssh(1) with arbitrary untrusted arguments, but getting this stuff right can be tricky, so this should prevent most obvious ways of creating risky situations. It however is not and cannot be perfect: ssh(1) has no practical way of interpreting what shell quoting rules are in use and how they interact with the user's specified ProxyCommand. To allow configurations that use strange user or hostnames to continue to work, this strictness is applied only to names coming from the commandline. Names specified using User or Hostname directives in ssh_config(5) are not affected. feedback/ok millert@ markus@ dtucker@ deraadt@ OpenBSD-Commit-ID: 3b487348b5964f3e77b6b4d3da4c3b439e94b2d9 (cherry picked from commit c39254c8f23379709b8e2a68dc64477d2885f1d4)
-rw-r--r--crypto/openssh/ssh.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/crypto/openssh/ssh.c b/crypto/openssh/ssh.c
index 8469f8edbb48..55a28f0ea1ff 100644
--- a/crypto/openssh/ssh.c
+++ b/crypto/openssh/ssh.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh.c,v 1.594 2023/09/03 23:59:32 djm Exp $ */
+/* $OpenBSD: ssh.c,v 1.599 2023/12/18 14:47:44 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -624,6 +624,41 @@ ssh_conn_info_free(struct ssh_conn_info *cinfo)
free(cinfo);
}
+static int
+valid_hostname(const char *s)
+{
+ size_t i;
+
+ if (*s == '-')
+ return 0;
+ for (i = 0; s[i] != 0; i++) {
+ if (strchr("'`\"$\\;&<>|(){}", s[i]) != NULL ||
+ isspace((u_char)s[i]) || iscntrl((u_char)s[i]))
+ return 0;
+ }
+ return 1;
+}
+
+static int
+valid_ruser(const char *s)
+{
+ size_t i;
+
+ if (*s == '-')
+ return 0;
+ for (i = 0; s[i] != 0; i++) {
+ if (strchr("'`\";&<>|(){}", s[i]) != NULL)
+ return 0;
+ /* Disallow '-' after whitespace */
+ if (isspace((u_char)s[i]) && s[i + 1] == '-')
+ return 0;
+ /* Disallow \ in last position */
+ if (s[i] == '\\' && s[i + 1] == '\0')
+ return 0;
+ }
+ return 1;
+}
+
/*
* Main program for the ssh client.
*/
@@ -1122,6 +1157,10 @@ main(int ac, char **av)
if (!host)
usage();
+ if (!valid_hostname(host))
+ fatal("hostname contains invalid characters");
+ if (options.user != NULL && !valid_ruser(options.user))
+ fatal("remote username contains invalid characters");
options.host_arg = xstrdup(host);
/* Initialize the command to execute on remote host. */