From ec9cc725d598ac77de7b6df8afeec292b3c8ad46 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 24 Nov 2020 14:56:57 +0100 Subject: [PATCH] ftp: CURLOPT_FTP_SKIP_PASV_IP by default The command line tool also independently sets --ftp-skip-pasv-ip by default. Ten test cases updated to adapt the modified --libcurl output. Bug: https://curl.se/docs/CVE-2020-8284.html CVE-2020-8284 Reported-by: Varnavas Papaioannou Upstream-Status: Backport [https://github.com/curl/curl/commit/ec9cc725d598ac] CVE: CVE-2020-8284 Signed-off-by: Chee Yang Lee --- docs/cmdline-opts/ftp-skip-pasv-ip.d | 2 ++ docs/libcurl/opts/CURLOPT_FTP_SKIP_PASV_IP.3 | 8 +++++--- lib/url.c | 1 + src/tool_cfgable.c | 1 + tests/data/test1400 | 1 + tests/data/test1401 | 1 + tests/data/test1402 | 1 + tests/data/test1403 | 1 + tests/data/test1404 | 1 + tests/data/test1405 | 1 + tests/data/test1406 | 1 + tests/data/test1407 | 1 + tests/data/test1420 | 1 + 14 files changed, 18 insertions(+), 3 deletions(-) diff --git a/docs/cmdline-opts/ftp-skip-pasv-ip.d b/docs/cmdline-opts/ftp-skip-pasv-ip.d index d6fd4589b1e..bcf4e7e62f2 100644 --- a/docs/cmdline-opts/ftp-skip-pasv-ip.d +++ b/docs/cmdline-opts/ftp-skip-pasv-ip.d @@ -10,4 +10,6 @@ to curl's PASV command when curl connects the data connection. Instead curl will re-use the same IP address it already uses for the control connection. +Since curl 7.74.0 this option is enabled by default. + This option has no effect if PORT, EPRT or EPSV is used instead of PASV. diff --git a/docs/libcurl/opts/CURLOPT_FTP_SKIP_PASV_IP.3 b/docs/libcurl/opts/CURLOPT_FTP_SKIP_PASV_IP.3 index d6217d0d8ca..fa87ddce769 100644 --- a/docs/libcurl/opts/CURLOPT_FTP_SKIP_PASV_IP.3 +++ b/docs/libcurl/opts/CURLOPT_FTP_SKIP_PASV_IP.3 @@ -5,7 +5,7 @@ .\" * | (__| |_| | _ <| |___ .\" * \___|\___/|_| \_\_____| .\" * -.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. +.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. .\" * .\" * This software is licensed as described in the file COPYING, which .\" * you should have received as part of this distribution. The terms @@ -35,11 +35,13 @@ address it already uses for the control connection. But it will use the port number from the 227-response. This option thus allows libcurl to work around broken server installations -that due to NATs, firewalls or incompetence report the wrong IP address back. +that due to NATs, firewalls or incompetence report the wrong IP address +back. Setting the option also reduces the risk for various sorts of client +abuse by malicious servers. This option has no effect if PORT, EPRT or EPSV is used instead of PASV. .SH DEFAULT -0 +1 since 7.74.0, was 0 before then. .SH PROTOCOLS FTP .SH EXAMPLE diff --git a/lib/url.c b/lib/url.c index f8b2a0030de..2b0ba87ba87 100644 --- a/lib/url.c +++ b/lib/url.c @@ -497,6 +497,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data) set->ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */ set->ftp_use_pret = FALSE; /* mainly useful for drftpd servers */ set->ftp_filemethod = FTPFILE_MULTICWD; + set->ftp_skip_ip = TRUE; /* skip PASV IP by default */ #endif set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */ diff --git a/src/tool_cfgable.c b/src/tool_cfgable.c index c52d8e1c6bb..4c06d3557b7 100644 --- a/src/tool_cfgable.c +++ b/src/tool_cfgable.c @@ -44,6 +44,7 @@ void config_init(struct OperationConfig *config) config->tcp_nodelay = TRUE; /* enabled by default */ config->happy_eyeballs_timeout_ms = CURL_HET_DEFAULT; config->http09_allowed = FALSE; + config->ftp_skip_ip = TRUE; } static void free_config_fields(struct OperationConfig *config) diff --git a/tests/data/test1400 b/tests/data/test1400 index 812ad0b88d9..b7060eca58e 100644 --- a/tests/data/test1400 +++ b/tests/data/test1400 @@ -73,6 +73,7 @@ int main(int argc, char *argv[]) curl_easy_setopt(hnd, CURLOPT_USERAGENT, "stripped"); curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L); curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L); curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L); /* Here is a list of options the curl code used that cannot get generated diff --git a/tests/data/test1401 b/tests/data/test1401 index f93b3d637de..a2629683aff 100644 --- a/tests/data/test1401 +++ b/tests/data/test1401 @@ -87,6 +87,7 @@ int main(int argc, char *argv[]) curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L); curl_easy_setopt(hnd, CURLOPT_COOKIE, "chocolate=chip"); curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L); curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L); curl_easy_setopt(hnd, CURLOPT_PROTOCOLS, (long)CURLPROTO_FILE | (long)CURLPROTO_FTP | diff --git a/tests/data/test1402 b/tests/data/test1402 index 7593c516da1..1bd55cb4e3b 100644 --- a/tests/data/test1402 +++ b/tests/data/test1402 @@ -78,6 +78,7 @@ int main(int argc, char *argv[]) curl_easy_setopt(hnd, CURLOPT_USERAGENT, "stripped"); curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L); curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L); curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L); /* Here is a list of options the curl code used that cannot get generated diff --git a/tests/data/test1403 b/tests/data/test1403 index ecb4dd3dcab..a7c9fcca322 100644 --- a/tests/data/test1403 +++ b/tests/data/test1403 @@ -73,6 +73,7 @@ int main(int argc, char *argv[]) curl_easy_setopt(hnd, CURLOPT_USERAGENT, "stripped"); curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L); curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L); curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L); /* Here is a list of options the curl code used that cannot get generated diff --git a/tests/data/test1404 b/tests/data/test1404 index 97622b63948..1d8e8cf7779 100644 --- a/tests/data/test1404 +++ b/tests/data/test1404 @@ -147,6 +147,7 @@ int main(int argc, char *argv[]) curl_easy_setopt(hnd, CURLOPT_USERAGENT, "stripped"); curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L); curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L); curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L); /* Here is a list of options the curl code used that cannot get generated diff --git a/tests/data/test1405 b/tests/data/test1405 index 2bac79eda74..b4087704f7b 100644 --- a/tests/data/test1405 +++ b/tests/data/test1405 @@ -89,6 +89,7 @@ int main(int argc, char *argv[]) curl_easy_setopt(hnd, CURLOPT_POSTQUOTE, slist2); curl_easy_setopt(hnd, CURLOPT_PREQUOTE, slist3); curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L); curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L); /* Here is a list of options the curl code used that cannot get generated diff --git a/tests/data/test1406 b/tests/data/test1406 index 51a166adff2..38f68d11ee1 100644 --- a/tests/data/test1406 +++ b/tests/data/test1406 @@ -79,6 +79,7 @@ int main(int argc, char *argv[]) curl_easy_setopt(hnd, CURLOPT_URL, "smtp://%HOSTIP:%SMTPPORT/1406"); curl_easy_setopt(hnd, CURLOPT_UPLOAD, 1L); curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L); curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L); curl_easy_setopt(hnd, CURLOPT_MAIL_FROM, "sender@example.com"); curl_easy_setopt(hnd, CURLOPT_MAIL_RCPT, slist1); diff --git a/tests/data/test1407 b/tests/data/test1407 index f6879008fb2..a7e13ba7585 100644 --- a/tests/data/test1407 +++ b/tests/data/test1407 @@ -62,6 +62,7 @@ int main(int argc, char *argv[]) curl_easy_setopt(hnd, CURLOPT_DIRLISTONLY, 1L); curl_easy_setopt(hnd, CURLOPT_USERPWD, "user:secret"); curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L); curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L); /* Here is a list of options the curl code used that cannot get generated diff --git a/tests/data/test1420 b/tests/data/test1420 index 057ecc4773a..4b8d7bbf418 100644 --- a/tests/data/test1420 +++ b/tests/data/test1420 @@ -67,6 +67,7 @@ int main(int argc, char *argv[]) curl_easy_setopt(hnd, CURLOPT_URL, "imap://%HOSTIP:%IMAPPORT/1420/;MAILINDEX=1"); curl_easy_setopt(hnd, CURLOPT_USERPWD, "user:secret"); curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L); curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L); /* Here is a list of options the curl code used that cannot get generated