Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libcurl believes that FTP control channel is secure when connecting through a HTTPS proxy #5523

Closed
mingtaoy opened this issue Jun 5, 2020 · 0 comments

Comments

@mingtaoy
Copy link

@mingtaoy mingtaoy commented Jun 5, 2020

I did this

curl_easy_setopt(curl, CURLOPT_URL, "ftp://some.ftp.server");
curl_easy_setopt(curl, CURLOPT_PROTOCOLS, CURLPROTO_FTP);
curl_easy_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, 1);
curl_easy_setopt(curl, CURLOPT_PROXY, "proxy:443");
curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTPS);
curl_easy_setopt(curl, CURLOPT_USERPWD, "...");

I observed the following:

curl correctly connects to the HTTPS proxy and issues a CONNECT to establish an (insecure) control connection to the destination FTP server.

The issue, I believe, is due to these lines here:

curl/lib/ftp.c

Lines 2500 to 2504 in 42ed22f

static CURLcode ftp_state_loggedin(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
if(conn->ssl[FIRSTSOCKET].use) {

Specifically, conn->ssl[FIRSTSOCKET].use is set to true, despite the fact that the destination is an insecure FTP server.

After libcurl authenticates on the control connection, it sends the PBSZ command followed by PROT. This is in violation of RFC 4217, which states:

      Note: In line with [RFC-2228], there is no facility for securing
      the Data connection with an insecure Control connection.
      Specifically, the PROT command MUST be preceded by a PBSZ command,
      and a PBSZ command MUST be preceded by a successful security data
      exchange (the TLS negotiation in this case).

Normally, this would not be an issue, but in one bizarre case, the FTP server was responding with "200" in response to the PROT command, which leads to curl attempting a TLS handshake on the data connection, even though the destination server was not prepared for it.

curl/lib/ftp.c

Lines 2732 to 2743 in 42ed22f

case FTP_PBSZ:
PPSENDF(&ftpc->pp, "PROT %c",
data->set.use_ssl == CURLUSESSL_CONTROL ? 'C' : 'P');
state(conn, FTP_PROT);
break;
case FTP_PROT:
if(ftpcode/100 == 2)
/* We have enabled SSL for the data connection! */
conn->bits.ftp_use_data_ssl =
(data->set.use_ssl != CURLUSESSL_CONTROL) ? TRUE : FALSE;

curl/libcurl version

Tested on trunk (as of 2020/06/04), on commit c048dd0.

operating system

Linux localhost 5.4.0-26-generic #30-Ubuntu SMP Mon Apr 20 16:58:30 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

bagder added a commit that referenced this issue Sep 24, 2020
When using HTTPS proxy, SSL is used but not in the view of the FTP
protocol handler itself so separate the connection's use of SSL from the
FTP control connection's sue.

Fixes #5523
@bagder bagder closed this in 1397a7d Sep 24, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

2 participants
You can’t perform that action at this time.