fs: improve sanitization
Signed-off-by: Varun Patil <radialapps@gmail.com>pull/888/head
parent
73cc86c4a1
commit
f69765a42a
|
@ -72,6 +72,7 @@ class ArchiveController extends GenericApiController
|
|||
$fileStorageId = $file->getStorage()->getId();
|
||||
$parent = $file->getParent();
|
||||
$isArchived = false;
|
||||
$depth = 0;
|
||||
while (true) {
|
||||
/** @psalm-suppress DocblockTypeContradiction */
|
||||
if (null === $parent) {
|
||||
|
@ -98,12 +99,17 @@ class ArchiveController extends GenericApiController
|
|||
}
|
||||
|
||||
// Hit an archive folder root
|
||||
if ($parent->getName() === \OCA\Memories\Util::$ARCHIVE_FOLDER) {
|
||||
if (Util::ARCHIVE_FOLDER === $parent->getName()) {
|
||||
$isArchived = true;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Too deep
|
||||
if (++$depth > 32) {
|
||||
throw new \Exception('[Archive] Max recursion depth exceeded');
|
||||
}
|
||||
|
||||
$parent = $parent->getParent();
|
||||
}
|
||||
|
||||
|
@ -133,8 +139,10 @@ class ArchiveController extends GenericApiController
|
|||
$parent = $parent->getParent();
|
||||
} else {
|
||||
// file not in archive, put it in there
|
||||
$af = \OCA\Memories\Util::$ARCHIVE_FOLDER;
|
||||
$destinationPath = Util::sanitizePath($af.$relativeFilePath);
|
||||
$destinationPath = Util::sanitizePath(Util::ARCHIVE_FOLDER.$relativeFilePath);
|
||||
if (null === $destinationPath) {
|
||||
throw Exceptions::BadRequest('Invalid archive destination path');
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the filename
|
||||
|
|
|
@ -189,10 +189,11 @@ class PublicController extends AuthPublicShareController
|
|||
$foldersPath = Util::sanitizePath('/'.$foldersPath.'/');
|
||||
|
||||
// Check if relPath starts with foldersPath
|
||||
if (!str_starts_with($relPath, $foldersPath)) {
|
||||
if (empty($foldersPath) || !str_starts_with($relPath, $foldersPath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var string $foldersPath */
|
||||
// Remove foldersPath from start of relPath
|
||||
$relPath = substr($relPath, \strlen($foldersPath));
|
||||
|
||||
|
|
|
@ -114,14 +114,16 @@ class FsManager
|
|||
|
||||
try {
|
||||
foreach ($paths as $path) {
|
||||
$node = $userFolder->get(Util::sanitizePath($path));
|
||||
$root->addFolder($node);
|
||||
$etag .= $node->getEtag();
|
||||
if ($sanitized = Util::sanitizePath($path)) {
|
||||
$node = $userFolder->get($sanitized);
|
||||
$root->addFolder($node);
|
||||
$etag .= $node->getEtag();
|
||||
} else {
|
||||
throw new \Exception("invalid path {$path}");
|
||||
}
|
||||
}
|
||||
} catch (\OCP\Files\NotFoundException $e) {
|
||||
$msg = $e->getMessage();
|
||||
|
||||
throw new \Exception("Folder not found: {$msg}");
|
||||
} catch (\Exception $e) {
|
||||
throw new \Exception("Folder not found: {$e->getMessage()}");
|
||||
}
|
||||
|
||||
// Add shares or external stores inside the current folders
|
||||
|
|
19
lib/Util.php
19
lib/Util.php
|
@ -18,7 +18,7 @@ class Util
|
|||
{
|
||||
use UtilController;
|
||||
|
||||
public static string $ARCHIVE_FOLDER = '.archive';
|
||||
public const ARCHIVE_FOLDER = '.archive';
|
||||
|
||||
/**
|
||||
* Get host CPU architecture (amd64 or aarch64).
|
||||
|
@ -336,20 +336,27 @@ class Util
|
|||
?: self::getSystemConfig('memories.timeline.default_path');
|
||||
|
||||
return array_map(
|
||||
static fn ($p) => self::sanitizePath(trim($p)),
|
||||
static fn ($path) => self::sanitizePath(trim($path))
|
||||
?? throw new \InvalidArgumentException("Invalid timeline path: {$path}"),
|
||||
explode(';', $paths),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize a path to keep only ASCII characters and special characters.
|
||||
* Blank will be returned on error.
|
||||
* Null will be returned on error.
|
||||
*/
|
||||
public static function sanitizePath(string $path): string
|
||||
public static function sanitizePath(string $path): ?string
|
||||
{
|
||||
$path = str_replace("\0", '', $path); // remove null characters
|
||||
// remove double slashes and such
|
||||
$normalized = \OC\Files\Filesystem::normalizePath($path, false);
|
||||
|
||||
return mb_ereg_replace('\/\/+', '/', $path) ?: ''; // remove extra slashes
|
||||
// look for invalid characters and pattern
|
||||
if (!\OC\Files\Filesystem::isValidPath($normalized)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $normalized;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue