Add a description
Summary
ZFile's share link system exposes two endpoints for interacting with shared content:
POST /api/share/files — browse shared files (correctly enforces shareEntries filter)
GET /api/share/download/{shareKey}?path=<file> — download a file from a share
The download endpoint does not validate that the requested path belongs to the shareEntries list specified when the share was created. Any recipient of a share link can use the download endpoint to retrieve any file within the shared directory's base path (sharePath), not just the files the owner explicitly shared.
Details
When a user creates a share link in ZFile, they specify:
storageKey — which storage source to share from
sharePath — the base directory (e.g., /shared)
shareEntries — the specific files/folders within that directory to expose (e.g., ["public.txt"])
Browse endpoint (ShareLinkFileService.getShareFileList): correctly calls getFilteredRootFileList, which filters the file listing to only items in shareEntries.
Download endpoint (ShareLinkFileService.getShareFileDownloadUrl) at line ~90 of ShareLinkFileService.java:
public String getShareFileDownloadUrl(String shareKey, String filePath, String password) {
ShareLink shareLink = getValidShareLink(shareKey);
validateSharePassword(shareLink, password);
AbstractBaseFileService<?> fileService = StorageSourceContext.getByStorageKey(shareLink.getStorageKey());
// ...
// ❌ No check: is filePath one of shareLink.getShareEntries()?
return fileService.getDownloadUrl(StringUtils.concat(shareLink.getSharePath(), filePath));
}
The method validates the share key and password but never verifies that filePath corresponds to a file in shareEntries. Since filePath is a raw HTTP query parameter, an attacker who has a valid share key (e.g., as a legitimate recipient of a share) can request any arbitrary path within sharePath/.
PoC
(available upon request)
Impact
Any recipient of a ZFile share link (including unauthenticated users with the link) can download any file in the sharePath directory of that storage source, not just the files the owner chose to expose. In multi-user deployments, this allows:
- Reading private files in the same directory as the shared file
- Enumerating the directory content by guessing file names (since file listing is filtered but download is not)
- On local storage backends, any file path within
sharePath/ is accessible
The severity depends on how narrowly sharePath is scoped. If users share from / (the root), the attacker can access all files in the storage source.
Add a description
Summary
ZFile's share link system exposes two endpoints for interacting with shared content:
POST /api/share/files— browse shared files (correctly enforcesshareEntriesfilter)GET /api/share/download/{shareKey}?path=<file>— download a file from a shareThe download endpoint does not validate that the requested
pathbelongs to theshareEntrieslist specified when the share was created. Any recipient of a share link can use the download endpoint to retrieve any file within the shared directory's base path (sharePath), not just the files the owner explicitly shared.Details
When a user creates a share link in ZFile, they specify:
storageKey— which storage source to share fromsharePath— the base directory (e.g.,/shared)shareEntries— the specific files/folders within that directory to expose (e.g.,["public.txt"])Browse endpoint (
ShareLinkFileService.getShareFileList): correctly callsgetFilteredRootFileList, which filters the file listing to only items inshareEntries.Download endpoint (
ShareLinkFileService.getShareFileDownloadUrl) at line ~90 ofShareLinkFileService.java:The method validates the share key and password but never verifies that
filePathcorresponds to a file inshareEntries. SincefilePathis a raw HTTP query parameter, an attacker who has a valid share key (e.g., as a legitimate recipient of a share) can request any arbitrary path withinsharePath/.PoC
(available upon request)
Impact
Any recipient of a ZFile share link (including unauthenticated users with the link) can download any file in the
sharePathdirectory of that storage source, not just the files the owner chose to expose. In multi-user deployments, this allows:sharePath/is accessibleThe severity depends on how narrowly
sharePathis scoped. If users share from/(the root), the attacker can access all files in the storage source.