From 465166a94034faffcaa1e1af468e88ccfd524db0 Mon Sep 17 00:00:00 2001 From: Kalle Olavi Niemitalo Date: Sun, 18 Mar 2007 08:53:56 +0200 Subject: [PATCH] Reject CR and LF characters in FTP pathnames. [ Bug 942; backported from commit adfde652b99c297bc05fd4876249669cc34a01ad in ELinks 0.12.GIT. --KON ] --- src/protocol/ftp/ftp.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/protocol/ftp/ftp.c b/src/protocol/ftp/ftp.c index a4be62f0b..fe3380106 100644 --- a/src/protocol/ftp/ftp.c +++ b/src/protocol/ftp/ftp.c @@ -637,6 +637,26 @@ get_ftp_data_socket(struct connection *conn, struct string *command) return 1; } +/* Check if the file or directory name @s can be safely sent to the + * FTP server. To prevent command injection attacks, this function + * must reject CR LF sequences. */ +static int +is_ftp_pathname_safe(const struct string *s) +{ + int i; + + /* RFC 959 says the argument of CWD and RETR is a , + * which consists of s, "any of the 128 ASCII characters + * except and ". So other control characters, such + * as 0x00 and 0x7F, are allowed here. Bytes 0x80...0xFF + * should not be allowed, but if we reject them, users will + * probably complain. */ + for (i = 0; i < s->length; i++) { + if (s->source[i] == 0x0A || s->source[i] == 0x0D) + return 0; + } + return 1; +} /* Create passive socket and add appropriate announcing commands to str. Then * go and retrieve appropriate object from server. @@ -703,6 +723,13 @@ add_file_cmd_to_str(struct connection *conn) add_to_string(&command, "CWD "); add_uri_to_string(&uri_string, conn->uri, URI_PATH); decode_uri_string(&uri_string); + if (!is_ftp_pathname_safe(&uri_string)) { + done_string(&uri_string); + done_string(&command); + done_string(&ftp_data_command); + abort_connection(conn, S_BAD_URL); + return NULL; + } add_string_to_string(&command, &uri_string); add_crlf_to_string(&command); @@ -745,6 +772,13 @@ add_file_cmd_to_str(struct connection *conn) add_to_string(&command, "RETR "); add_uri_to_string(&uri_string, conn->uri, URI_PATH); decode_uri_string(&uri_string); + if (!is_ftp_pathname_safe(&uri_string)) { + done_string(&uri_string); + done_string(&command); + done_string(&ftp_data_command); + abort_connection(conn, S_BAD_URL); + return NULL; + } add_string_to_string(&command, &uri_string); add_crlf_to_string(&command); done_string(&uri_string);