Package: curl Version: 7.88.1-10+deb12u8 Severity: important Tags: patch upstream
Curl package is currently in breach of "secure by default" Debian policy. When I launch curl without ~/.ssh/known_host file curl will connect to any host without any host identity validation, rather than refusing the connection as expected. Here's how to demonstrate the issue: $ mv ~/.ssh/known_hosts ~/.ssh/known_hosts.backup $ curl -u bob:hunter2 sftp://target.invalid/file After testing restore the previous known_hosts file: $ mv ~/.ssh/known_hosts.backup ~/.ssh/known_hosts Due to a curl logic flaw the connection is established to target.invalid host without validating the host identity. Anyone in a privileged network position is able to spoof the SSH server. The impact is quite serious, as the malicious server can: 1. In case of download send malicious content back 2. In case of upload capture the uploaded content 3. Steal the username & password (if password auth is used) I expect curl command to fail if the host identity cannot be validated. The issue is described in detail here: https://sintonen.fi/advisories/curl-ssh-insufficient-host-identity-verification.txt or: https://www.openwall.com/lists/oss-security/2025/02/05/4 A proposed patch to fix this issue is: ---8<--- diff --git a/src/tool_operate.c b/src/tool_operate.c index 007a5e054..52e10a5f5 100644 --- a/src/tool_operate.c +++ b/src/tool_operate.c @@ -1170,14 +1170,13 @@ static CURLcode config2setopts(struct GlobalConfig *global, /* new in curl 7.19.6 */ result = res_setopt_str(curl, CURLOPT_SSH_KNOWNHOSTS, known); curl_free(known); - if(result == CURLE_UNKNOWN_OPTION) - /* libssh2 version older than 1.1.1 */ - result = CURLE_OK; - if(result) - return result; } - else + else { warnf(global, "Couldn't find a known_hosts file"); + result = res_setopt_str(curl, CURLOPT_SSH_KNOWNHOSTS, ""); + } + if(result) + return result; } } ---8<--- -- System Information: Debian Release: 12.9 APT prefers stable-updates APT policy: (500, 'stable-updates'), (500, 'stable-security'), (500, 'stable') Architecture: amd64 (x86_64) Kernel: Linux 6.1.0-28-amd64 (SMP w/8 CPU threads; PREEMPT) Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE not set Shell: /bin/sh linked to /usr/bin/dash Init: sysvinit (via /sbin/init) LSM: AppArmor: enabled Versions of packages curl depends on: ii libc6 2.36-9+deb12u9 ii libcurl4 7.88.1-10+deb12u8 ii zlib1g 1:1.2.13.dfsg-1 curl recommends no packages. curl suggests no packages. -- no debconf information
diff --git a/src/tool_operate.c b/src/tool_operate.c index 007a5e054..52e10a5f5 100644 --- a/src/tool_operate.c +++ b/src/tool_operate.c @@ -1170,14 +1170,13 @@ static CURLcode config2setopts(struct GlobalConfig *global, /* new in curl 7.19.6 */ result = res_setopt_str(curl, CURLOPT_SSH_KNOWNHOSTS, known); curl_free(known); - if(result == CURLE_UNKNOWN_OPTION) - /* libssh2 version older than 1.1.1 */ - result = CURLE_OK; - if(result) - return result; } - else + else { warnf(global, "Couldn't find a known_hosts file"); + result = res_setopt_str(curl, CURLOPT_SSH_KNOWNHOSTS, ""); + } + if(result) + return result; } }
diff --git a/src/tool_operate.c b/src/tool_operate.c index 007a5e054..52e10a5f5 100644 --- a/src/tool_operate.c +++ b/src/tool_operate.c @@ -1170,14 +1170,13 @@ static CURLcode config2setopts(struct GlobalConfig *global, /* new in curl 7.19.6 */ result = res_setopt_str(curl, CURLOPT_SSH_KNOWNHOSTS, known); curl_free(known); - if(result == CURLE_UNKNOWN_OPTION) - /* libssh2 version older than 1.1.1 */ - result = CURLE_OK; - if(result) - return result; } - else + else { warnf(global, "Couldn't find a known_hosts file"); + result = res_setopt_str(curl, CURLOPT_SSH_KNOWNHOSTS, ""); + } + if(result) + return result; } }
diff --git a/src/tool_operate.c b/src/tool_operate.c index 007a5e054..52e10a5f5 100644 --- a/src/tool_operate.c +++ b/src/tool_operate.c @@ -1170,14 +1170,13 @@ static CURLcode config2setopts(struct GlobalConfig *global, /* new in curl 7.19.6 */ result = res_setopt_str(curl, CURLOPT_SSH_KNOWNHOSTS, known); curl_free(known); - if(result == CURLE_UNKNOWN_OPTION) - /* libssh2 version older than 1.1.1 */ - result = CURLE_OK; - if(result) - return result; } - else + else { warnf(global, "Couldn't find a known_hosts file"); + result = res_setopt_str(curl, CURLOPT_SSH_KNOWNHOSTS, ""); + } + if(result) + return result; } }