Files
Salvatore Martire 1c8993e065 fix: fail uploads when uri does not match session
This is a cosmetic change that can cause false security reports: the
current implementation of the upload root collection returns UploadHome
in every case, based on the current session, either the one of the
logged in user, or for the share. The former allows uploading files in
what looks like the upload folder of another user, but is in reality the
one of the logged in user. Those requests will now fail with a 403
instead.

Signed-off-by: Salvatore Martire <4652631+salmart-dev@users.noreply.github.com>
2026-09-03 17:35:03 +02:00

61 lines
1.5 KiB
PHP

<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\DAV\Upload;
use OCP\Files\IRootFolder;
use OCP\IUserSession;
use OCP\Share\IManager;
use Sabre\DAV\Exception\Forbidden;
use Sabre\DAV\INode;
use Sabre\DAVACL\AbstractPrincipalCollection;
use Sabre\DAVACL\PrincipalBackend;
class RootCollection extends AbstractPrincipalCollection {
public function __construct(
PrincipalBackend\BackendInterface $principalBackend,
string $principalPrefix,
private CleanupService $cleanupService,
private IRootFolder $rootFolder,
private IUserSession $userSession,
private IManager $shareManager,
) {
parent::__construct($principalBackend, $principalPrefix);
$this->disableListing = true;
}
/**
* @inheritdoc
*/
public function getChildForPrincipal(array $principalInfo): INode|UploadHome {
[$prefix, $name] = \Sabre\Uri\split($principalInfo['uri']);
$user = $this->userSession->getUser();
if ($prefix !== 'principals/shares' && $user?->getUID() !== $name) {
// if the request is not using a share token and the URL does not match the user, error out
throw new Forbidden('Not allowed');
}
return new UploadHome(
$principalInfo,
$this->cleanupService,
$this->rootFolder,
$this->userSession,
$this->shareManager,
);
}
/**
* @inheritdoc
*/
public function getName(): string {
return 'uploads';
}
}