⚠️ This issue respects the following points: ⚠️
Bug description
Uploading a file through an "upload only" / file-request public share link that points inside a group folder stores the file with a broken permission set. Afterwards the team members who have access to the group folder can no longer view, edit or delete the dropped file.
This worked correctly in 32.0.9 and broke in 32.0.10.
Root cause: the public WebDAV endpoint apps/dav/appinfo/v2/publicremote.php (and the legacy apps/dav/appinfo/v1/publicwebdav.php) changed its sharePermissions storage wrapper from a whole-storage OC\Files\Storage\Wrapper\PermissionsMask to a OC\Files\Storage\Wrapper\DirPermissionsMask hard-coded to 'path' => 'files':
return new DirPermissionsMask([
'storage' => $storage,
'mask' => $mask,
'path' => 'files',
]);
DirPermissionsMask::checkPath() only applies the mask to storage-internal paths equal to or under files/. That assumption is only valid for a user home storage (where shared content lives under files/, next to siblings like files_versions/, files_trashbin/, uploads/). A group folder is mounted as a Jail rooted at the group folder's own files area, so its internal storage paths do not carry a files/ prefix. checkPath() therefore never matches, the share mask is bypassed, and isCreatable()/isUpdatable()/isDeletable()/getPermissions() fall through to the unmasked underlying storage. As a result files dropped through an upload-only public link inside a group folder are recorded with the wrong permission set. 32.0.9 used the whole-storage PermissionsMask, which masks consistently regardless of storage layout, so the bug did not occur.
The files/-only masking was introduced in #59511 (to keep versions/trashbin usable for public shares on home storages) and extended to the v2 endpoint in #59654 ("Fix permission issue when uploading a chunked file"), which shipped in 32.0.10. The intent is correct for home storages, but the hard-coded 'files' path is wrong for jailed storages such as group folders.
Suggested fix: choose the masking strategy by storage type — keep DirPermissionsMask(path => 'files') for IHomeStorage, and use the whole-storage PermissionsMask for everything else (group folders / jailed / external storages), in both the v1 and v2 endpoints.
Steps to reproduce
- Create a group folder and give a group write access to it.
- Create a public share link on a folder inside that group folder and set it to "File request" / upload only (create permission only).
- Open the public link as an anonymous user and upload a file.
- As a group member, open the group folder and try to view/edit/delete the uploaded file.
Expected behavior
The uploaded file is stored with the normal group-folder permissions, so group members can read, edit and delete it (same as in 32.0.9).
Nextcloud Server version
32
Operating system
Debian/Ubuntu
PHP engine version
None
Web server
Apache (supported)
Database engine version
MySQL
Is this bug present after an update or on a fresh install?
Fresh Nextcloud Server install
Are you using the Nextcloud Server Encryption module?
None
What user-backends are you using?
Configuration report
List of activated Apps
Enabled:
- activity: 5.0.0
- announcementcenter: 7.4.0
- app_api: 32.0.0
- bruteforcesettings: 5.0.0
- calendar: 6.4.2
- circles: 32.0.0
- cloud_federation_api: 1.16.0
- comments: 1.22.0
- contacts: 8.3.12
- contactsinteraction: 1.13.1
- dashboard: 7.12.0
- dav: 1.34.2
- end_to_end_encryption: 1.18.2
- federatedfilesharing: 1.22.0
- federation: 1.22.0
- files: 2.4.0
- files_downloadlimit: 5.0.0
- files_pdfviewer: 5.0.0
- files_reminders: 1.5.0
- files_sharing: 1.24.1
- files_trashbin: 1.22.0
- files_versions: 1.25.0
- firstrunwizard: 5.0.0
- groupfolders: 20.1.13
- impersonate: 3.0.1
- logreader: 5.0.0
- lookup_server_connector: 1.20.0
- mail: 5.8.2
- notifications: 5.0.0
- notify_push: 1.3.3
- oauth2: 1.20.0
- onlyoffice: 9.13.0
- password_policy: 4.0.0
- passwords: 2026.5.10
- photos: 5.0.0
- privacy: 4.0.0
- profile: 1.1.0
- provisioning_api: 1.22.0
- recommendations: 5.0.0
- related_resources: 3.0.0
- richdocuments: 9.0.6
- serverinfo: 4.0.0
- settings: 1.15.1
- sharebymail: 1.22.0
- systemtags: 1.22.0
- text: 6.0.2
- theming: 2.7.0
- theming_customcss: 1.20.0
- twofactor_backupcodes: 1.21.0
- twofactor_webauthn: 2.6.0
- user_status: 1.12.0
- viewer: 5.0.0
- weather_status: 1.12.0
- webhook_listeners: 1.3.0
- workflowengine: 2.14.0
Disabled:
- admin_audit: 1.22.0
- encryption: 2.20.0
- files_external: 1.24.1
- nextcloud_announcements: 4.0.0 (installed 1.12.0)
- support: 4.0.0 (installed 1.6.0)
- survey_client: 4.0.0 (installed 1.11.0)
- suspicious_login: 10.0.0
- twofactor_nextcloud_notification: 6.0.0
- twofactor_totp: 14.0.0
- updatenotification: 1.22.0 (installed 1.18.0)
- user_ldap: 1.23.0
Nextcloud Signing status
Nextcloud Logs
Additional info
The bug is present in v33.0.5, as well as in a fresh install of v30.0.10 and v30.0.11.
Regression introduced between v32.0.9 and v32.0.10 by commit 6b05ce6 (stable32 backport of #59654), a follow-up to #59511.
The legacy v1 endpoint apps/dav/appinfo/v1/publicwebdav.php carries the identical bug and should be fixed together with v2.
I think that the problem comes instead from getMetadata not being implemented for DirPermissionsMask. When a file is uploaded the file is scanned and its metadata is added to the cache. As DirPermissionsMask::getMetadata is not implemented it falls back to PermissionsMask::getMetadata, which restricts the permissions independently of the path. Although the metadata to be added to the cache contains masked permissions it also provides scan_permissions with the original ones, so before storing the permissions in the cache they are "reverted" to the original ones. Therefore, right after adding the file to the cache for the first time the permissions are the expected ones. But that is not the end of the story :-)
After storing the initial metadata if the request contains a modification time the cache is updated with it (which will be allowed by the DirPermissionsMask as the file is not in the path and thus the touch is delegated to the storage). This triggers another scan, which again gets the metadata with masked permissions even if the file is not in the path. However, as this is now a rescan there is cached data, but as the file is not in the path in this case the permissions are not masked, so the cached data contains a permissions entry with the right value (the same originally set) and no scan_permissions (which would have been set by the CachePermissionsMask if the path matched). Due to that, when the differences between the new data and the cached one are calculated the result is that permissions changed to the masked ones, but scan_permissions did not, so when added again to the cache the masked permissions are not "reverted" to the original ones like before and the masked permissions end stored in the cache. Due to all that the file does not have read, edit or delete permissions when accessed as a logged in user.
Note that getMetadata is not implemented either in DirMask in the guests app where DirPermissionsMask comes from, so if getMetadata should be added to DirPermissionsMask I guess it might need to be added to DirMask too.
Alternatively (or in addition?) to implementing getMetadata in DirPermissionsMask it might be necessary too to always set scan_permissions even if it did not change when calculating the differences between the new data and the cached one, as the cached value could be based already on scan_permissons rather than on permissions 🤔
Bug description
Uploading a file through an "upload only" / file-request public share link that points inside a group folder stores the file with a broken permission set. Afterwards the team members who have access to the group folder can no longer view, edit or delete the dropped file.
This worked correctly in 32.0.9 and broke in 32.0.10.
Root cause: the public WebDAV endpoint
apps/dav/appinfo/v2/publicremote.php(and the legacyapps/dav/appinfo/v1/publicwebdav.php) changed itssharePermissionsstorage wrapper from a whole-storageOC\Files\Storage\Wrapper\PermissionsMaskto aOC\Files\Storage\Wrapper\DirPermissionsMaskhard-coded to'path' => 'files':DirPermissionsMask::checkPath()only applies the mask to storage-internal paths equal to or underfiles/. That assumption is only valid for a user home storage (where shared content lives underfiles/, next to siblings likefiles_versions/,files_trashbin/,uploads/). A group folder is mounted as aJailrooted at the group folder's own files area, so its internal storage paths do not carry afiles/prefix.checkPath()therefore never matches, the share mask is bypassed, andisCreatable()/isUpdatable()/isDeletable()/getPermissions()fall through to the unmasked underlying storage. As a result files dropped through an upload-only public link inside a group folder are recorded with the wrong permission set. 32.0.9 used the whole-storagePermissionsMask, which masks consistently regardless of storage layout, so the bug did not occur.The
files/-only masking was introduced in #59511 (to keep versions/trashbin usable for public shares on home storages) and extended to the v2 endpoint in #59654 ("Fix permission issue when uploading a chunked file"), which shipped in 32.0.10. The intent is correct for home storages, but the hard-coded'files'path is wrong for jailed storages such as group folders.Suggested fix: choose the masking strategy by storage type — keep
DirPermissionsMask(path => 'files')forIHomeStorage, and use the whole-storagePermissionsMaskfor everything else (group folders / jailed / external storages), in both the v1 and v2 endpoints.Steps to reproduce
Expected behavior
The uploaded file is stored with the normal group-folder permissions, so group members can read, edit and delete it (same as in 32.0.9).
Nextcloud Server version
32
Operating system
Debian/Ubuntu
PHP engine version
None
Web server
Apache (supported)
Database engine version
MySQL
Is this bug present after an update or on a fresh install?
Fresh Nextcloud Server install
Are you using the Nextcloud Server Encryption module?
None
What user-backends are you using?
Configuration report
List of activated Apps
Nextcloud Signing status
Nextcloud Logs
Additional info
The bug is present in
v33.0.5, as well as in a fresh install ofv30.0.10andv30.0.11.Regression introduced between
v32.0.9andv32.0.10by commit6b05ce6(stable32 backport of #59654), a follow-up to #59511.The legacy v1 endpoint
apps/dav/appinfo/v1/publicwebdav.phpcarries the identical bug and should be fixed together with v2.