diff --git a/source/packages/com_mokosuitebackup/sql/install.mysql.sql b/source/packages/com_mokosuitebackup/sql/install.mysql.sql index 94b07d74..a3ae77db 100644 --- a/source/packages/com_mokosuitebackup/sql/install.mysql.sql +++ b/source/packages/com_mokosuitebackup/sql/install.mysql.sql @@ -6,7 +6,7 @@ CREATE TABLE IF NOT EXISTS `#__mokosuitebackup_profiles` ( `archive_format` VARCHAR(10) NOT NULL DEFAULT 'zip', `compression_level` TINYINT(1) UNSIGNED NOT NULL DEFAULT 5 COMMENT '0=none, 9=max', `split_size` INT(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '0=no split, otherwise MB per part', - `backup_dir` VARCHAR(512) NOT NULL DEFAULT 'administrator/components/com_mokosuitebackup/backups', + `backup_dir` VARCHAR(512) NOT NULL DEFAULT '[DEFAULT_DIR]', `archive_name_format` VARCHAR(512) NOT NULL DEFAULT '[host]_[datetime]_profile[profile_id]' COMMENT 'Filename format with placeholders', `exclude_dirs` TEXT NOT NULL COMMENT 'Newline-separated directory paths to exclude', `exclude_files` TEXT NOT NULL COMMENT 'Newline-separated filename patterns to exclude', @@ -81,7 +81,7 @@ INSERT IGNORE INTO `#__mokosuitebackup_profiles` ( `published`, `ordering`, `created`, `modified` ) VALUES ( 1, 'Default Backup Profile', 'Full site backup with default settings', 'full', - 'zip', 5, 0, 'administrator/components/com_mokosuitebackup/backups', + 'zip', 5, 0, '[DEFAULT_DIR]', 'administrator/components/com_mokosuitebackup/backups\ntmp\ncache\nlogs\nadministrator/logs', '.gitignore\n.htaccess.bak', '#__session', diff --git a/source/packages/com_mokosuitebackup/src/Controller/AjaxController.php b/source/packages/com_mokosuitebackup/src/Controller/AjaxController.php index 94d5d8be..66bca3d1 100644 --- a/source/packages/com_mokosuitebackup/src/Controller/AjaxController.php +++ b/source/packages/com_mokosuitebackup/src/Controller/AjaxController.php @@ -82,7 +82,10 @@ class AjaxController extends BaseController } $requestPath = $this->input->getString('path', JPATH_ROOT); - $path = realpath($requestPath) ?: $requestPath; + + // Resolve placeholders and relative paths before permission check + $resolved = BackupDirectory::resolve($requestPath); + $path = realpath($resolved) ?: $resolved; // Security: restrict browsing to site root and current user's home $jRoot = realpath(JPATH_ROOT); diff --git a/source/packages/com_mokosuitebackup/src/Field/FolderPickerField.php b/source/packages/com_mokosuitebackup/src/Field/FolderPickerField.php index 175f086a..166a6c1a 100644 --- a/source/packages/com_mokosuitebackup/src/Field/FolderPickerField.php +++ b/source/packages/com_mokosuitebackup/src/Field/FolderPickerField.php @@ -96,6 +96,9 @@ class FolderPickerField extends FormField Browse +
@@ -107,6 +110,44 @@ class FolderPickerField extends FormField The default backup directory is inside the web root. Backup archives may be directly downloadable if .htaccess is not supported. For better security, use a path outside the web root.
+