0521bb
diff --git a/ssh.c b/ssh.c
0521bb
index 35c48e62..48d93ddf 100644
0521bb
--- a/ssh.c
0521bb
+++ b/ssh.c
0521bb
@@ -626,6 +626,41 @@ ssh_conn_info_free(struct ssh_conn_info *cinfo)
0521bb
 	free(cinfo);
0521bb
 }
0521bb
 
0521bb
+static int
0521bb
+valid_hostname(const char *s)
0521bb
+{
0521bb
+	size_t i;
0521bb
+
0521bb
+	if (*s == '-')
0521bb
+		return 0;
0521bb
+	for (i = 0; s[i] != 0; i++) {
0521bb
+		if (strchr("'`\"$\\;&<>|(){}", s[i]) != NULL ||
0521bb
+		    isspace((u_char)s[i]) || iscntrl((u_char)s[i]))
0521bb
+			return 0;
0521bb
+	}
0521bb
+	return 1;
0521bb
+}
0521bb
+
0521bb
+static int
0521bb
+valid_ruser(const char *s)
0521bb
+{
0521bb
+	size_t i;
0521bb
+
0521bb
+	if (*s == '-')
0521bb
+		return 0;
0521bb
+	for (i = 0; s[i] != 0; i++) {
0521bb
+		if (strchr("'`\";&<>|(){}", s[i]) != NULL)
0521bb
+			return 0;
0521bb
+		/* Disallow '-' after whitespace */
0521bb
+		if (isspace((u_char)s[i]) && s[i + 1] == '-')
0521bb
+			return 0;
0521bb
+		/* Disallow \ in last position */
0521bb
+		if (s[i] == '\\' && s[i + 1] == '\0')
0521bb
+			return 0;
0521bb
+	}
0521bb
+	return 1;
0521bb
+}
0521bb
+
0521bb
 /*
0521bb
  * Main program for the ssh client.
0521bb
  */
0521bb
@@ -1118,6 +1153,10 @@ main(int ac, char **av)
0521bb
 	if (!host)
0521bb
 		usage();
0521bb
 
0521bb
+	if (!valid_hostname(host))
0521bb
+		fatal("hostname contains invalid characters");
0521bb
+	if (options.user != NULL && !valid_ruser(options.user))
0521bb
+		fatal("remote username contains invalid characters");
0521bb
 	host_arg = xstrdup(host);
0521bb
 
0521bb
 	/* Initialize the command to execute on remote host. */