CVE-2026-45159
Description
A vulnerability in Nextcloud's End-to-End Encryption app allowed unauthorized file uploads to restricted folders via manipulated file drop links.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
A vulnerability in Nextcloud's End-to-End Encryption app allowed unauthorized file uploads to restricted folders via manipulated file drop links.
Vulnerability
The vulnerability exists in the Nextcloud End-to-End Encryption application, specifically affecting versions 1.15.0 through 1.15.3, 1.16.0 through 1.16.2, 1.17.0, and 1.18.0 [2]. The issue stems from a failure to properly validate the share structure for file drop metadata, allowing the application to incorrectly process file drop requests [1].
Exploitation
An attacker requires access to an end-to-end encrypted files drop link to exploit this flaw. By interacting with the share, the attacker can leverage the insufficient validation to upload files into unintended end-to-end encrypted folders belonging to the share owner [2].
Impact
Successful exploitation allows an unauthorized user to drop files into folders they should not have access to within the share owner's directory. The vulnerability does not permit the reading or modification of existing files, limiting the impact to unauthorized file placement [2].
Mitigation
Users should upgrade the End-to-End Encryption app to versions 1.15.4, 1.16.3, 1.17.1, 1.18.1, or 2.0.0-rc.7 to resolve this issue [2]. No workarounds are available for this vulnerability [2].
AI Insight generated on Jun 1, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
1Patches
1e11c1db2a1dcMerge pull request #1395 from nextcloud/fix/filedrop-metadata
1 file changed · +36 −15
lib/Controller/MetaDataController.php+36 −15 modified@@ -261,7 +261,14 @@ public function deleteMetaData(int $id): DataResponse { */ #[PublicPage] public function addMetadataFileDrop(int $id, string $filedrop, ?string $shareToken = null): DataResponse { - $ownerId = $this->getOwnerId($shareToken); + if ($this->userId === null && $shareToken === null) { + throw new OCSBadRequestException("No 'shareToken' provided and user is not logged in"); + } + + /** @var string */ + $ownerId = $shareToken + ? $this->getFileDropOwnerId($shareToken, $id) + : $this->userId; try { $userFolder = $this->rootFolder->getUserFolder($ownerId); @@ -270,9 +277,8 @@ public function addMetadataFileDrop(int $id, string $filedrop, ?string $shareTok } if ($userFolder->getId() === $id) { - $e = new OCSForbiddenException($this->l10n->t('You are not allowed to lock the root')); - $this->logger->error($e->getMessage(), ['exception' => $e]); - throw $e; + $this->logger->error('Cannot create filedrop lock on root folder of user {userId}', ['userId' => $ownerId]); + throw new OCSForbiddenException($this->l10n->t('You are not allowed to create the lock')); } $nodes = $userFolder->getById($id); @@ -309,19 +315,34 @@ public function addMetadataFileDrop(int $id, string $filedrop, ?string $shareTok return new DataResponse(['filedrop' => json_decode($filedrop, true)]); } - private function getOwnerId(?string $shareToken = null): string { - if ($shareToken !== null) { - $share = $this->shareManager->getShareByToken($shareToken); + private function getFileDropOwnerId(string $shareToken, int $fileId): string { + $share = $this->shareManager->getShareByToken($shareToken); - if (!($share->getPermissions() & \OCP\Constants::PERMISSION_CREATE)) { - throw new OCSForbiddenException("Can't lock share without create permission"); - } - - return $share->getShareOwner(); - } elseif ($this->userId !== null) { + // if we are the owner of the node shared via the share, we can directly return our user id + if ($this->userId !== null && $share->getShareOwner() === $this->userId) { return $this->userId; - } else { - throw new OCSBadRequestException("Couldn't find the owner of the encrypted folder"); } + + if (!($share->getPermissions() & \OCP\Constants::PERMISSION_CREATE)) { + throw new OCSForbiddenException($this->l10n->t('You are not allowed to create the lock')); + } + + $shareRoot = $share->getNode(); + if (!$shareRoot instanceof Folder) { + $this->logger->error('Cannot create filedrop lock on non-folder share {share}', ['share' => $shareToken]); + throw new OCSForbiddenException($this->l10n->t('You are not allowed to create the lock')); + } + + if (!$shareRoot->isEncrypted()) { + $this->logger->error('Cannot create filedrop lock on non-encrypted folders of {share}', ['share' => $shareToken]); + throw new OCSForbiddenException($this->l10n->t('You are not allowed to create the lock')); + } + + if ($shareRoot->getId() !== $fileId && ($shareRoot instanceof Folder && $shareRoot->getFirstNodeById($fileId) === null)) { + $this->logger->error('Cannot create filedrop lock on node outside of share {share}', ['share' => $shareToken, 'fileId' => $fileId]); + throw new OCSForbiddenException($this->l10n->t('You are not allowed to create the lock')); + } + + return $share->getShareOwner(); } }
Vulnerability mechanics
No source-code context for this CVE — mechanics is only generated when we can read the actual fix diff. Without that, the four sections (root cause, attack vector, affected code, fix) would be speculation rather than analysis.
References
3News mentions
0No linked articles in our index yet.