VYPR
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.

PackageAffected versionsPatched versions
copypartyPyPI
< 1.19.81.19.8

Affected products

1

Patches

1
e0a92ba72d46

fence 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

News mentions

0

No linked articles in our index yet.