Correctly sanitize requested backup files - #939
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This pull request tightens backup file handling in BackupController to reduce directory traversal risk by validating that requested backup files resolve inside the configured backup directory, and introduces Path::dirname() / Path::basename() utilities to centralize path manipulation behavior.
Changes:
- Added
Path::dirname()andPath::basename()helpers for separator-agnostic path operations. - Updated backup creation to use
Path::basename()when returning the generated backup filename. - Updated backup download/delete to validate resolved paths and to raise
TranslatedExceptionfor invalid filenames.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| formwork/src/Utils/Path.php | Adds dirname() / basename() helpers to standardize path component extraction. |
| formwork/src/Panel/Controllers/BackupController.php | Uses the new Path helpers and strengthens validation/error handling for download/delete operations. |
Suppressed comments (1)
formwork/src/Panel/Controllers/BackupController.php:81
- Same issue as in
download(): strictPath::dirname($file) === $backupPathbreaks whensystem.backup.pathhas a trailing/, and the decoded route param should be strict-base64 decoded + validated as a single filename component before joining paths.
$backupPath = Path::normalize($this->config->getString('system.backup.path'));
$file = FileSystem::joinPaths($backupPath, base64_decode((string) $routeParams->get('backup')));
if (Path::dirname($file) === $backupPath && FileSystem::isFile($file, assertExists: false)) {
FileSystem::delete($file);
$this->panel->notify($this->translate('panel.backup.deleted'), 'success');
return $this->redirectToReferer(default: $this->generateRoute('panel.tools.backups'), base: $this->generateRoute('panel.index'));
}
throw new TranslatedException('Invalid backup filename', 'panel.backup.error.cannotDelete.invalidFilename');
馃挕 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This pull request enhances the security and reliability of backup file management in the
BackupControllerby improving path handling and validation, and by introducing new utility methods in thePathclass. The main focus is to prevent directory traversal vulnerabilities and ensure that only valid backup files within the configured backup directory can be accessed, downloaded, or deleted.Backup file path handling and validation:
BackupController, file operations for download and delete now ensure the resolved file is within the normalized backup path by checkingPath::dirname($file) === $backupPath, preventing directory traversal attacks. Errors now throwTranslatedExceptionfor better error messaging. [1] [2]Path::basenameinstead of the built-inbasenamefor more robust path handling.Utility methods in
Pathclass:Path::dirnameandPath::basenamemethods to provide consistent, cross-platform path manipulation, replacing direct usage of PHP鈥檚dirnameandbasename.Imports update:
BackupController.phpto use the newPathutility class.