mirror of
https://github.com/tiennm99/coolify.git
synced 2026-04-17 17:21:04 +00:00
Major architectural improvements: - Merged download and restore into single atomic operation - Eliminated separate S3DownloadFinished event (redundant) - Files now transfer directly: S3 → helper container → server → database container - Removed download progress tracking in favor of unified restore progress UI/UX improvements: - Unified restore method selection with visual cards - Consistent "File Information" display between local and S3 restore - Single slide-over for all restore operations (removed separate S3 download monitor) - Better visual feedback with loading states Security enhancements: - Added isSafeTmpPath() helper for path traversal protection - URL decode validation to catch encoded attacks - Canonical path resolution to prevent symlink attacks - Comprehensive path validation in all cleanup events Cleanup improvements: - S3RestoreJobFinished now handles all cleanup (helper container + all temp files) - RestoreJobFinished uses new isSafeTmpPath() validation - CoolifyTask dispatches cleanup events even on job failure - All cleanup uses non-throwing commands (2>/dev/null || true) Other improvements: - S3 storage policy authorization on Show component - Storage Form properly syncs is_usable state after test - Removed debug code and improved error handling - Better command organization and documentation 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
62 lines
1.9 KiB
PHP
62 lines
1.9 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Security tests for RestoreJobFinished event to ensure it uses secure path validation.
|
|
*/
|
|
describe('RestoreJobFinished event security', function () {
|
|
it('validates that safe paths pass validation', function () {
|
|
$validPaths = [
|
|
'/tmp/restore-backup.sql',
|
|
'/tmp/restore-script.sh',
|
|
'/tmp/database-dump-'.uniqid().'.sql',
|
|
];
|
|
|
|
foreach ($validPaths as $path) {
|
|
expect(isSafeTmpPath($path))->toBeTrue();
|
|
}
|
|
});
|
|
|
|
it('validates that malicious paths fail validation', function () {
|
|
$maliciousPaths = [
|
|
'/tmp/../etc/passwd',
|
|
'/tmp/foo/../../etc/shadow',
|
|
'/etc/sensitive-file',
|
|
'/var/www/config.php',
|
|
'/tmp/../../../root/.ssh/id_rsa',
|
|
];
|
|
|
|
foreach ($maliciousPaths as $path) {
|
|
expect(isSafeTmpPath($path))->toBeFalse();
|
|
}
|
|
});
|
|
|
|
it('rejects URL-encoded path traversal attempts', function () {
|
|
$encodedTraversalPaths = [
|
|
'/tmp/%2e%2e/etc/passwd',
|
|
'/tmp/foo%2f%2e%2e%2f%2e%2e/etc/shadow',
|
|
urlencode('/tmp/../etc/passwd'),
|
|
];
|
|
|
|
foreach ($encodedTraversalPaths as $path) {
|
|
expect(isSafeTmpPath($path))->toBeFalse();
|
|
}
|
|
});
|
|
|
|
it('handles edge cases correctly', function () {
|
|
// Too short
|
|
expect(isSafeTmpPath('/tmp'))->toBeFalse();
|
|
expect(isSafeTmpPath('/tmp/'))->toBeFalse();
|
|
|
|
// Null/empty
|
|
expect(isSafeTmpPath(null))->toBeFalse();
|
|
expect(isSafeTmpPath(''))->toBeFalse();
|
|
|
|
// Null byte injection
|
|
expect(isSafeTmpPath("/tmp/file.sql\0../../etc/passwd"))->toBeFalse();
|
|
|
|
// Valid edge cases
|
|
expect(isSafeTmpPath('/tmp/x'))->toBeTrue();
|
|
expect(isSafeTmpPath('/tmp/very/deeply/nested/path/to/file.sql'))->toBeTrue();
|
|
});
|
|
});
|