Skip to content

Commit 2bb7704

Browse files
Merge pull request #4386 from nextcloud/backport/4368/stable31
[stable31] fix(FolderController): Sanitize mountpoints correctly
2 parents 281e389 + b40a07b commit 2bb7704

File tree

5 files changed

+74
-13
lines changed

5 files changed

+74
-13
lines changed

lib/Command/Create.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ protected function configure(): void {
3030
}
3131

3232
protected function execute(InputInterface $input, OutputInterface $output): int {
33-
$id = $this->folderManager->createFolder($input->getArgument('name'));
33+
$id = $this->folderManager->createFolder($this->folderManager->trimMountpoint((string)$input->getArgument('name')));
3434
$output->writeln((string)$id);
3535

3636
return 0;

lib/Command/Rename.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
2828
return -1;
2929
}
3030

31-
$this->folderManager->renameFolder($folder['id'], $input->getArgument('name'));
31+
$this->folderManager->renameFolder($folder['id'], $this->folderManager->trimMountpoint((string)$input->getArgument('name')));
3232

3333
return 0;
3434
}

lib/Controller/FolderController.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -220,13 +220,14 @@ private function getRootFolderStorageId(): ?int {
220220
#[NoAdminRequired]
221221
#[FrontpageRoute(verb: 'POST', url: '/folders')]
222222
public function addFolder(string $mountpoint): DataResponse {
223+
$mountpoint = $this->manager->trimMountpoint($mountpoint);
223224

224225
$storageId = $this->rootFolder->getMountPoint()->getNumericStorageId();
225226
if ($storageId === null) {
226227
throw new OCSNotFoundException();
227228
}
228229

229-
$id = $this->manager->createFolder(trim($mountpoint));
230+
$id = $this->manager->createFolder($mountpoint);
230231
$folder = $this->manager->getFolder($id, $storageId);
231232
if ($folder === null) {
232233
throw new OCSNotFoundException();
@@ -280,7 +281,8 @@ public function removeFolder(int $id): DataResponse {
280281
#[NoAdminRequired]
281282
#[FrontpageRoute(verb: 'PUT', url: '/folders/{id}')]
282283
public function setMountPoint(int $id, string $mountPoint): DataResponse {
283-
$this->manager->renameFolder($id, trim($mountPoint));
284+
$mountPoint = $this->manager->trimMountpoint($mountPoint);
285+
$this->manager->renameFolder($id, $mountPoint);
284286
return new DataResponse(['success' => true]);
285287
}
286288

@@ -457,7 +459,8 @@ public function renameFolder(int $id, string $mountpoint): DataResponse {
457459
return $response;
458460
}
459461

460-
$this->manager->renameFolder($id, trim($mountpoint));
462+
$mountpoint = $this->manager->trimMountpoint($mountpoint);
463+
$this->manager->renameFolder($id, $mountpoint);
461464

462465
return new DataResponse(['success' => true]);
463466
}

lib/Folder/FolderManager.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
use OC\Files\Cache\Cache;
1010
use OC\Files\Cache\CacheEntry;
11+
use OC\Files\Filesystem;
1112
use OC\Files\Node\Node;
1213
use OCA\Circles\CirclesManager;
1314
use OCA\Circles\Exceptions\CircleNotFoundException;
@@ -20,6 +21,7 @@
2021
use OCA\GroupFolders\Mount\FolderStorageManager;
2122
use OCA\GroupFolders\Mount\GroupMountPoint;
2223
use OCA\GroupFolders\ResponseDefinitions;
24+
use OCP\AppFramework\OCS\OCSBadRequestException;
2325
use OCP\AutoloadNotAllowedException;
2426
use OCP\Constants;
2527
use OCP\DB\Exception;
@@ -767,6 +769,31 @@ public function getFoldersFromCircleMemberships(IUser $user, int $rootStorageId
767769
], array_values($query->executeQuery()->fetchAll()));
768770
}
769771

772+
public function trimMountpoint(string $mountpoint): string {
773+
// Remove whitespace
774+
$mountpoint = trim($mountpoint);
775+
776+
$mountpoint = FileSystem::normalizePath($mountpoint);
777+
778+
// Used to mount a Team folder at the user's home.
779+
if ($mountpoint === '/') {
780+
return $mountpoint;
781+
}
782+
783+
// Remove leading slash
784+
$mountpoint = substr($mountpoint, 1);
785+
786+
if (str_contains($mountpoint, '..')) {
787+
throw new OCSBadRequestException('Mount point cannot contain ".."');
788+
}
789+
790+
// Check if the new mountpoint is valid
791+
if ($mountpoint === '') {
792+
throw new OCSBadRequestException('Mount point cannot be empty');
793+
}
794+
795+
return $mountpoint;
796+
}
770797

771798
/**
772799
* @throws Exception

src/settings/App.tsx

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@ import AdminGroupSelect from './AdminGroupSelect'
1818
import SubAdminGroupSelect from './SubAdminGroupSelect'
1919
import { loadState } from '@nextcloud/initial-state'
2020
import { t } from '@nextcloud/l10n'
21+
import { isAxiosError } from '@nextcloud/axios'
22+
import { getLoggerBuilder } from '@nextcloud/logger'
23+
24+
const logger = getLoggerBuilder()
25+
.setApp('groupfolders')
26+
.detectUser()
27+
.build()
2128

2229
const bytesInOneGibibyte = Math.pow(1024, 3)
2330
const defaultQuotaOptions = {
@@ -96,10 +103,22 @@ export class App extends Component<unknown, AppState> implements OC.Plugin<OC.Se
96103
if (!mountPoint) {
97104
return
98105
}
99-
const folder = await this.api.createFolder(mountPoint)
100-
const folders = this.state.folders
101-
folders.push(folder)
102-
this.setState({ folders, newMountPoint: '' })
106+
try {
107+
const folder = await this.api.createFolder(mountPoint)
108+
const folders = this.state.folders
109+
folders.push(folder)
110+
this.setState({ folders, newMountPoint: '' })
111+
} catch (error) {
112+
logger.error('Error while creating new folder', { error })
113+
114+
if (isAxiosError(error) && error.response?.data.message) {
115+
// @ts-expect-error TS2339
116+
window.OCP.Toast.error(error.response.data.message)
117+
} else {
118+
// @ts-expect-error TS2339
119+
window.OCP.Toast.error(t('groupfolders', 'Folder could not be created'))
120+
}
121+
}
103122
}
104123

105124
attach = (search: OC.Search.Core) => {
@@ -159,10 +178,22 @@ export class App extends Component<unknown, AppState> implements OC.Plugin<OC.Se
159178
}
160179

161180
async renameFolder(folder: Folder, newName: string) {
162-
await this.api.renameFolder(folder.id, newName)
163-
const folders = this.state.folders
164-
folder.mount_point = newName
165-
this.setState({ folders, editingMountPoint: 0 })
181+
try {
182+
await this.api.renameFolder(folder.id, newName)
183+
const folders = this.state.folders
184+
folder.mount_point = newName
185+
this.setState({ folders, editingMountPoint: 0 })
186+
} catch (error) {
187+
logger.error('Error while renaming folder', { error })
188+
189+
if (isAxiosError(error) && error.response?.data.message) {
190+
// @ts-expect-error TS2339
191+
window.OCP.Toast.error(error.response.data.message)
192+
} else {
193+
// @ts-expect-error TS2339
194+
window.OCP.Toast.error(t('groupfolders', 'Folder could not be renamed'))
195+
}
196+
}
166197
}
167198

168199
async setAcl(folder: Folder, acl: boolean) {

0 commit comments

Comments
 (0)