[Bug]: PR #54814 Incomplete fix allows to move shares into subdirectories
Nobody has claimed this yet.
- Dominant language
- PHP
- Stars
- 36.9k
- Forks
- 5.2k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 713
Description
⚠️ This issue respects the following points: ⚠️
- This is a bug, not a question or a configuration/webserver/proxy issue.
- This issue is not already reported on Github OR Nextcloud Community Forum (I've searched it).
- Nextcloud Server is up to date. See Maintenance and Release Schedule for supported versions.
- I agree to follow Nextcloud's Code of Conduct.
Bug description
The permission validation logic in PR #54814 contains a flaw. While move/copy operations to the root directory of shared folders are correctly denied, operations targeting subdirectories bypass validation and are improperly allowed.
Steps to reproduce
- User A creates folder "/share" and shares it with User B (sharing permission disabled, only edit and delete permissions enabled)
- User A uploads file "/share/test.txt"
- User B creates folder "/re-share" and shares it with User C (all permissions enabled)
- User B attempts operations:
- Move/copy to "/re-share/" → Correctly rejected (403 error)
- Move/copy to "/re-share/subfolder/" → Incorrectly allowed
Expected behavior
Both operations should be denied since User B lacks share permissions on the source folder "/share".
Nextcloud Server version
30
Operating system
None
PHP engine version
None
Web server
None
Database engine version
None
Is this bug present after an update or on a fresh install?
None
Are you using the Nextcloud Server Encryption module?
None
What user-backends are you using?
- Default user-backend (database)
- LDAP/ Active Directory
- SSO - SAML
- Other
Configuration report
List of activated Apps
Nextcloud Signing status
Nextcloud Logs
Additional info
Root Cause
Current code only validates the share status of the target node itself:
Code Path: apps/dav/lib/Connector/Sabre/SharesPlugin.php
$targetShares = $this->getShare($targetNode->getNode());
Required fix is to validate the share status of the entire path chain:
$targetShares = $this->getSharesInPath($target);
New Helper Function:
/**
* Check if the path is within any shared folder (stops at first found share)
*/
private function getSharesInPath(string $path): array {
$currentPath = $path;
while ($currentPath !== '' && $currentPath !== '/') {
try {
$node = $this->tree->getNodeForPath($currentPath);
if ($node instanceof DavNode) {
$nodeShares = $this->getShare($node->getNode());
if (!empty($nodeShares)) {
// Return immediately when share is found
return $nodeShares;
}
}
} catch (\Exception $e) {
// Path doesn't exist, continue to parent directory
}
// Move up to parent directory
$currentPath = dirname($currentPath);
if ($currentPath === '.') {
$currentPath = '';
}
}
return [];
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in apps/dav/lib/Connector/Sabre/SharesPlugin.php at the target share validation and compare it with the reported getSharesInPath approach. Reproduce the move/copy cases for /re-share/ and /re-share/subfolder/, then verify both are rejected when the source share lacks sharing permission.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php
- Domain
- authorization, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 38/100