Use stronger SSL and TLS versions when I use libcurl to connect to the sftp server

Q:When I Use libcurl to connect to the sftp server, SonarQube prompts me to Use stronger SSL and TLS versions at curl_easy_init(), but from what I understand, The libcurl library doesn’t seem to have a way to set the SSH protocol version. How can I avoid this problem?

What language is this for?
C

Which rule?
Weak SSL/TLS protocols should not be usedc:S4423

Why do you believe it’s a false-positive/false-negative?
I use the libcurl library to connect to the SFTP server, so I think there should be other scanning rules to avoid this problem if I can’t set the SSH protocol version

Are you using
SonarQube - Developer Edition v10.6 (92116)

How can we reproduce the problem? Give us a self-contained snippet of code (formatted text, no screenshots)
Here is some of the code:

CURL *curl = NULL;
curl = curl_easy_init();
if(curl)
{
	curl_easy_setopt(curl, CURLOPT_URL, remote_file_path_temp);//sftp url
	curl_easy_setopt(curl, CURLOPT_USERPWD, url_key);
	curl_easy_setopt(curl, CURLOPT_USERNAME, user_account_temp);
	curl_easy_setopt(curl, CURLOPT_PASSWORD, user_password_temp);
	curl_easy_setopt(curl, CURLOPT_RANGE, temp_str);
	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
	curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
	curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, connect_time);
	curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);//default: 0  nerver timeout
	curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, my_progress_callback);
	curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, NULL);
	curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
	curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
	curl_easy_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, opensocket);
	curl_easy_setopt(curl, CURLOPT_OPENSOCKETDATA, &sockfd);
	curl_easy_setopt(curl, CURLOPT_CLOSESOCKETFUNCTION, closecb);
	curl_easy_setopt(curl, CURLOPT_CLOSESOCKETDATA, &sockfd);
}

Hi @Vincent.W,

Thanks for reaching out to us.

You should be able to add the following line curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2); to your set-up to select a secure protocol.

Can you check if this already solves your problem and the issue reported by Sonar?

Thanks.

Philipp

HI Philipp
Thanks for your reply.

According to your suggestion,I have tried to add curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
But it doesn’t seem to work, and here’s the image with the error:

Looking forward to your reply again.
THX.

Vincent.

@Vincent.W, could you send us a reproducer for the translation unit that contains this potential false positive? This would allow us to debug the problem efficiently on our side. (Let me also know if sharing a reproducer is not a viable option for you.)

Here are the steps to create a reproducer:

  • Add the reproducer option to the scanner configuration:
    sonar.cfamily.reproducer="Full path to the .cpp file that has or includes the file that has the false-positive"
  • Re-running the scanner should generate a file named sonar-cfamily.reproducer in the project folder
  • Please share this file with me privately (I will send you a private message).

Best,
Philipp

Hey @Vincent.W,

I think I could identify the problem. Let me walk you through.

The following code obviously has a problem:

void problematic_setup() {
  CURL *curl = curl_easy_init();
  if (curl) {
    CURLcode res;
    curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
    res = curl_easy_perform(curl);
    curl_easy_cleanup(curl);
  }
}

You can fix it and resolve the issue reported by Sonar by explicitly specifying the SSL version to be used by adding the line I mentioned before such that the code looks like the following:

void better_setup() {
  CURL *curl = curl_easy_init();
  if (curl) {
    CURLcode res;
    curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
    curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
    res = curl_easy_perform(curl);
    curl_easy_cleanup(curl);
  }
}

However, if you add yet additional constraints on curl’s setup, it will, again, report an issue because the desired SSL version might not actually be set depending on the additional constraints. Hence, the following code will cause Sonar to report the usage of an insecure SSL version because of the additional constraint on the boolean p:

void too_many_additional_constraints_setup(bool p) {
  CURL *curl = curl_easy_init();
  if (curl && p) {
    CURLcode res;
    curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
    curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
    res = curl_easy_perform(curl);
    curl_easy_cleanup(curl);
  }
}

Instead, you could rewrite your code to make it slightly more defensive and resolve the reported issue as shown in the following:

void set_openssl_version_no_matter_what_setup(bool p) {
  CURL *curl = curl_easy_init();
  if (curl) {
    curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
    curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
    if (p) {
      CURLcode res;
      res = curl_easy_perform(curl);
      curl_easy_cleanup(curl);
    }
  }
}

Let me know if this successfully mitigates the issue on your end.

Philipp

Hi Philipp.
Thank you very much for your help. After making the changes based on your suggestion, the issue no longer appears in SonarQube.

However, setting the CURLOPT_SSLVERSION option in the function used to connect to SFTP seems a bit strange. This is because when connecting to SFTP, the curl library uses the SSH protocol.

Do I really need to set the CURLOPT_SSLVERSION option after curl_easy_init()? Even for an SFTP connection that uses the SSH protocol?

Hi @Vincent.W,

I’ve just checked, and indeed, the CURLOPT_SSLVERSION affects only the TLS-based protocols as per CURLOPT_SSLVERSION.

I’ve created a ticket to investigate and fix what looks like a false positive: SFTP uses SSH and should not be affected by the option in question. In the initial code you sent, the remote_file_path_temp seems to be a variable. Depending on whether our analyzer is able to check the actual contents of that variable, it’s likely that it still raises since it cannot be sure what protocol is being used.

Feel free to track progress at Jira.

Thanks again for reporting this.

Best,
Philipp

1 Like

HI Philipp
Thank you for your analysis and reply, and thank you for your help all the time

2 Likes

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.