From 9030828494fdb38a5940e28ac423999f372e7f0e Mon Sep 17 00:00:00 2001 From: ed Date: Wed, 7 Jan 2026 20:56:51 +0000 Subject: [PATCH] sftp: loosen stat restrictions (#1170); some sftp clients always expect correct stat results, even in write-only folders, so this slight info-leak must be allowed --- copyparty/sftpd.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/copyparty/sftpd.py b/copyparty/sftpd.py index 85a9275a..e832d8a8 100644 --- a/copyparty/sftpd.py +++ b/copyparty/sftpd.py @@ -420,16 +420,23 @@ class SFTP_Srv(paramiko.SFTPServerInterface): def _stat(self, vp: str) -> SATTR | int: try: - ap = self.v2a(vp, r=True)[0] + ap, vn, _ = self.v2a(vp) + if ( + self.uname not in vn.axs.uread + and self.uname not in vn.axs.uwrite + and self.uname not in vn.axs.uget + ): + self.log("stat(%s): EPERM" % (vp,)) + return SFTP_PERMISSION_DENIED st = bos.stat(ap) + self.log("stat(%s): %s" % (vp, st)) except: if vp.strip("/") or self.asrv.vfs.realpath: - try: - self.v2a(vp, w=True)[0] - except: - return SFTP_PERMISSION_DENIED + self.log("stat(%s): ENOENT" % (vp,)) + return SFTP_NO_SUCH_FILE zi = int(time.time()) st = os.stat_result((16877, -1, -1, 1, 1000, 1000, 8, zi, zi, zi)) + self.log("stat(%s): vfs-root") return SATTR.from_stat(st) def open(self, path: str, flags: int, attr: SATTR) -> paramiko.SFTPHandle | int: