Moderate severityNVD Advisory· Published Sep 9, 2025· Updated Sep 10, 2025
copyparty: Sharing a single file does not fully restrict access to other files in source folder
CVE-2025-58753
Description
Copyparty is a portable file server. In versions prior to 1.19.8, there was a missing permission-check in the shares feature (the shr global-option). When a share was created for just one file inside a folder, it was possible to access the other files inside that folder by guessing the filenames. It was not possible to descend into subdirectories in this manner; only the sibling files were accessible. This issue did not affect filekeys or dirkeys. Version 1.19.8 fixes the issue.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
copypartyPyPI | < 1.19.8 | 1.19.8 |
Affected products
1Patches
1e0a92ba72d46fence fileshares to just those files
1 file changed · +44 −2
copyparty/authsrv.py+44 −2 modified@@ -431,6 +431,8 @@ def __init__( self.get_dbv = self._get_dbv self.ls = self._ls + self.canonical = self._canonical + self.dcanonical = self._dcanonical def __repr__(self) -> str: return "VFS(%s)" % ( @@ -624,15 +626,15 @@ def _get_dbv(self, vrem: str) -> tuple["VFS", str]: vrem = vjoin(self.vpath[len(dbv.vpath) :].lstrip("/"), vrem) return dbv, vrem - def canonical(self, rem: str, resolve: bool = True) -> str: + def _canonical(self, rem: str, resolve: bool = True) -> str: """returns the canonical path (fully-resolved absolute fs path)""" ap = self.realpath if rem: ap += "/" + rem return absreal(ap) if resolve else ap - def dcanonical(self, rem: str) -> str: + def _dcanonical(self, rem: str) -> str: """resolves until the final component (filename)""" ap = self.realpath if rem: @@ -641,6 +643,44 @@ def dcanonical(self, rem: str) -> str: ad, fn = os.path.split(ap) return os.path.join(absreal(ad), fn) + def _canonical_shr(self, rem: str, resolve: bool = True) -> str: + """returns the canonical path (fully-resolved absolute fs path)""" + ap = self.realpath + if rem: + ap += "/" + rem + + rap = absreal(ap) + if self.shr_files: + assert self.shr_src # !rm + vn, rem = self.shr_src + chk = absreal(os.path.join(vn.realpath, rem)) + if chk != rap: + # not the dir itself; assert file allowed + ad, fn = os.path.split(rap) + if chk != ad or fn not in self.shr_files: + return "\n\n" + + return rap if resolve else ap + + def _dcanonical_shr(self, rem: str) -> str: + """resolves until the final component (filename)""" + ap = self.realpath + if rem: + ap += "/" + rem + + ad, fn = os.path.split(ap) + ad = absreal(ad) + if self.shr_files: + assert self.shr_src # !rm + vn, rem = self.shr_src + chk = absreal(os.path.join(vn.realpath, rem)) + if chk != absreal(ap): + # not the dir itself; assert file allowed + if ad != chk or fn not in self.shr_files: + return "\n\n" + + return os.path.join(ad, fn) + def _ls_nope( self, *a, **ka ) -> tuple[str, list[tuple[str, os.stat_result]], dict[str, "VFS"]]: @@ -2751,6 +2791,8 @@ def _reload(self, verbosity: int = 9) -> None: shn.shr_files = set(fns) shn.ls = shn._ls_shr + shn.canonical = shn._canonical_shr + shn.dcanonical = shn._dcanonical_shr else: shn.ls = shn._ls
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/advisories/GHSA-pxvw-4w88-6x95ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-58753ghsaADVISORY
- github.com/9001/copyparty/commit/e0a92ba72d46074209a9c304eb2a01ca0429e60cghsax_refsource_MISCWEB
- github.com/9001/copyparty/releases/tag/v1.19.8ghsax_refsource_MISCWEB
- github.com/9001/copyparty/security/advisories/GHSA-pxvw-4w88-6x95ghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.