From 4bcce2e5ea12c22f637e8503a39376e879960c3d 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. --- 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 ac2917a0..28457954 100644 --- a/src/protocol/ftp/ftp.c +++ b/src/protocol/ftp/ftp.c @@ -638,6 +638,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. @@ -704,6 +724,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); @@ -746,6 +773,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);