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