fix: enhance path sanitization in backup and log services to prevent directory traversal
This commit is contained in:
@@ -160,20 +160,21 @@ func (s *BackupService) addDirToZip(w *zip.Writer, srcDir, zipBase string) error
|
||||
// DeleteBackup removes a backup file
|
||||
func (s *BackupService) DeleteBackup(filename string) error {
|
||||
// Basic sanitization to prevent directory traversal
|
||||
clean := filepath.Base(filename)
|
||||
clean := filepath.Base(filepath.Clean(filename))
|
||||
return os.Remove(filepath.Join(s.BackupDir, clean))
|
||||
}
|
||||
|
||||
// GetBackupPath returns the full path to a backup file (for downloading)
|
||||
func (s *BackupService) GetBackupPath(filename string) string {
|
||||
clean := filepath.Base(filename)
|
||||
clean := filepath.Base(filepath.Clean(filename))
|
||||
return filepath.Join(s.BackupDir, clean)
|
||||
}
|
||||
|
||||
// RestoreBackup restores the database and caddy data from a zip archive
|
||||
func (s *BackupService) RestoreBackup(filename string) error {
|
||||
// 1. Verify backup exists
|
||||
srcPath := filepath.Join(s.BackupDir, filename)
|
||||
clean := filepath.Base(filepath.Clean(filename))
|
||||
srcPath := filepath.Join(s.BackupDir, clean)
|
||||
if _, err := os.Stat(srcPath); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -103,3 +103,24 @@ func TestBackupService_Restore_ZipSlip(t *testing.T) {
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "illegal file path")
|
||||
}
|
||||
|
||||
func TestBackupService_PathTraversal(t *testing.T) {
|
||||
tmpDir := t.TempDir()
|
||||
service := &BackupService{
|
||||
DataDir: filepath.Join(tmpDir, "data"),
|
||||
BackupDir: filepath.Join(tmpDir, "backups"),
|
||||
}
|
||||
os.MkdirAll(service.BackupDir, 0755)
|
||||
|
||||
// Test GetBackupPath with traversal
|
||||
// Should resolve to .../backups/passwd, NOT .../etc/passwd
|
||||
path := service.GetBackupPath("../../etc/passwd")
|
||||
expected := filepath.Join(service.BackupDir, "passwd")
|
||||
assert.Equal(t, expected, path)
|
||||
|
||||
// Test DeleteBackup with traversal
|
||||
// Should try to delete .../backups/passwd, fail because it doesn't exist
|
||||
err := service.DeleteBackup("../../etc/passwd")
|
||||
assert.Error(t, err)
|
||||
assert.True(t, os.IsNotExist(err))
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ func (s *LogService) ListLogs() ([]LogFile, error) {
|
||||
|
||||
// GetLogPath returns the absolute path to a log file if it exists and is valid
|
||||
func (s *LogService) GetLogPath(filename string) (string, error) {
|
||||
clean := filepath.Base(filename)
|
||||
clean := filepath.Base(filepath.Clean(filename))
|
||||
path := filepath.Join(s.LogDir, clean)
|
||||
|
||||
// Verify file exists
|
||||
|
||||
Reference in New Issue
Block a user