Skip to content
Permalink
Browse files Browse the repository at this point in the history
Don’t allow pointing a Local volume to a system directory
  • Loading branch information
brandonkelly committed Feb 16, 2021
1 parent 3f36fbe commit c17728f
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 0 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Expand Up @@ -10,6 +10,9 @@
- Adjusted GraphQL complexity values for relational fields.
- Updated Composer to 2.0.9.

### Security
- It’s no longer possible to save a Local volume with the File System Path setting set to a system directory (e.g. the `templates/` or `vendor/` folders).

## 3.6.6 - 2021-02-15

### Added
Expand Down
53 changes: 53 additions & 0 deletions src/volumes/Local.php
Expand Up @@ -12,6 +12,7 @@
use League\Flysystem\Adapter\Local as LocalAdapter;
use League\Flysystem\FileExistsException;
use League\Flysystem\FileNotFoundException;
use yii\validators\InlineValidator;

/**
* The local volume class. Handles the implementation of the local filesystem as a volume in
Expand Down Expand Up @@ -58,9 +59,61 @@ protected function defineRules(): array
{
$rules = parent::defineRules();
$rules[] = [['path'], 'required'];
$rules[] = [['path'], 'validatePath'];
return $rules;
}

/**
* @param string $attribute
* @param array|null $params
* @param InlineValidator $validator
* @param string $path
* @return void
* @since 3.6.7
*/
public function validatePath(string $attribute, ?array $params, InlineValidator $validator, string $path): void
{
if ($created = !file_exists($path)) {
FileHelper::createDirectory($path);
}

$path = realpath($this->getRootPath());

if ($path === false) {
return;
}

// Make sure it’s not within any of the system directories
$pathService = Craft::$app->getPath();
$systemDirs = [
Craft::getAlias('@contentMigrations'),
Craft::getAlias('@lib'),
$pathService->getComposerBackupsPath(false),
$pathService->getConfigBackupPath(false),
$pathService->getConfigDeltaPath(false),
$pathService->getConfigPath(),
$pathService->getDbBackupPath(false),
$pathService->getLogPath(false),
$pathService->getRebrandPath(false),
$pathService->getRuntimePath(false),
$pathService->getSiteTemplatesPath(),
$pathService->getSiteTranslationsPath(),
$pathService->getTestsPath(),
$pathService->getVendorPath(),
];

foreach ($systemDirs as $dir) {
$dir = realpath($dir);
if ($dir !== false && strpos($path . DIRECTORY_SEPARATOR, $dir . DIRECTORY_SEPARATOR) === 0) {
$validator->addError($this, $attribute, Craft::t('app', 'Local volumes cannot be located within system directories.'));
if ($created) {
FileHelper::removeDirectory($path);
}
break;
}
}
}

/**
* @inheritdoc
*/
Expand Down

0 comments on commit c17728f

Please sign in to comment.