Skip to content

SFTP path "/~" results in curl: (79) Error in the SSH layer #17534

Closed
@charles2910

Description

@charles2910

I did this

In 4e2b52b, sftp handling of ~ was restricted to sftp://url/~/ to fix CVE-2023-27534.

A bit later, #11001 was opened to report a regression because previously sftp://url/~ listed the home dir but now it wasn't working.

Then 91b53ef fixed it by resolving /~ to /home/<user>, but as far as I could test (bookworm's, trixie's and sid's versions), it actually doesn't work at all and we get a:

charles@enjoyed-hen:~/git/curl$ curl -k sftp://10.25.175.17/~ -u dan:danpwd
curl: (79) Error in the SSH layer

At the same time, /~/ gives:

charles@enjoyed-hen:~/git/curl$ curl -k sftp://10.25.175.17/~/ -u dan:danpwd
-rw-r--r--    1 dan      dan          3526 May 31 14:20 .bashrc
-rw-r--r--    1 dan      dan           807 May 31 14:20 .profile
-rw-------    1 dan      dan          1180 May 31 14:37 .viminfo
-rw-r--r--    1 dan      dan             4 May 31 14:21 dan_file1
-rw-------    1 dan      dan            94 May 31 14:37 .bash_history
-rw-r--r--    1 dan      dan           220 May 31 14:20 .bash_logout
drwxr-xr-x    4 root     root         4096 May 31 14:21 ..
drwxr-xr-x    2 dan      dan          4096 May 31 14:37 .

After debugging things with gdb, the problem is Curl_getworkingpath returning /home/<user> for the first case and /home/<user>/ for the second. Later in the code (in ssh_statemachine), it inspects the last char of sshp->path to decide if it's going to SSH_SFTP_READDIR_INIT or SSH_SFTP_DOWNLOAD_INIT. As you might have guessed by now, for the /~ case, it tries to download /home/<user> and things fail.

Here is a proposed patch to fix the issue:

From e8e59da93bdc76b9776c49ed7c1bfc7659504ebc Mon Sep 17 00:00:00 2001
From: Carlos Henrique Lima Melara <charlesmelara@riseup.net>
Date: Thu, 5 Jun 2025 02:32:50 +0000
Subject: [PATCH] curl_path: make SFTP path /~ returns /home/<user>/

---
 lib/vssh/curl_path.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/lib/vssh/curl_path.c b/lib/vssh/curl_path.c
index 117d2e600..be150f454 100644
--- a/lib/vssh/curl_path.c
+++ b/lib/vssh/curl_path.c
@@ -83,6 +83,11 @@ CURLcode Curl_getworkingpath(struct Curl_easy *data,
         free(working_path);
         return CURLE_OUT_OF_MEMORY;
       }
+    } else {
+      if(curlx_dyn_add(&npath, "/")) {
+        free(working_path);
+        return CURLE_OUT_OF_MEMORY;
+      }
     }
   }

--
2.47.2

I expected the following

No response

curl/libcurl version

curl 8.14.1 (x86_64-pc-linux-gnu) libcurl/8.14.1 OpenSSL/3.5.0 zlib/1.3.1 brotli/1.1.0 zstd/1.5.7 libidn2/2.3.8 libpsl/0.21.2 libssh2/1.11.1 nghttp2/1.64.0 nghttp3/1.8.0 librtmp/2.3 OpenLDAP/2.6.9
Release-Date: 2025-06-04, security patched: 8.14.1-2
Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp ws wss
Features: alt-svc AsynchDNS brotli GSS-API HSTS HTTP2 HTTP3 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM PSL SPNEGO SSL threadsafe TLS-SRP UnixSockets zstd

operating system

Debian testing

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions