diff --git a/cmd/updater/updater_windows.go b/cmd/updater/updater_windows.go index 03dd6b42..6f603ca5 100644 --- a/cmd/updater/updater_windows.go +++ b/cmd/updater/updater_windows.go @@ -37,15 +37,17 @@ func installByInstaller(killSignalChan chan<- any, packagePath, destDir string) } defer reader.Close() - // Find the installer file var installerPath string for _, file := range reader.File { + cleanName := filepath.Clean(file.Name) + if strings.HasPrefix(cleanName, "..") || filepath.IsAbs(cleanName) { + continue + } if file.FileInfo().IsDir() { continue } - // Extract file - path := filepath.Join(tempDir, file.Name) + path := filepath.Join(tempDir, cleanName) if err := os.MkdirAll(filepath.Dir(path), os.ModePerm); err != nil { return err @@ -101,7 +103,11 @@ func installByPortable(killSignalChan chan<- any, packagePath, destDir string) e defer reader.Close() for _, file := range reader.File { - path := filepath.Join(destDir, file.Name) + cleanName := filepath.Clean(file.Name) + if strings.HasPrefix(cleanName, "..") || filepath.IsAbs(cleanName) { + continue + } + path := filepath.Join(destDir, cleanName) if file.FileInfo().IsDir() { os.MkdirAll(path, file.Mode()) diff --git a/pkg/download/extract.go b/pkg/download/extract.go index f092d2f5..2f6ef03c 100644 --- a/pkg/download/extract.go +++ b/pkg/download/extract.go @@ -282,19 +282,15 @@ func countArchiveFiles(archivePath string, password string) (int, error) { // extractFile handles extracting a single file from an archive func extractFile(ctx context.Context, fileInfo archives.FileInfo, destDir string) error { - // Skip directories, they will be created when extracting files - if fileInfo.IsDir() { - destPath := filepath.Join(destDir, fileInfo.NameInArchive) - return os.MkdirAll(destPath, fileInfo.Mode()) - } - - // Sanitize the path to prevent path traversal attacks cleanPath := filepath.Clean(fileInfo.NameInArchive) if strings.HasPrefix(cleanPath, "..") || filepath.IsAbs(cleanPath) { - // Skip files with suspicious paths return nil } + if fileInfo.IsDir() { + return os.MkdirAll(filepath.Join(destDir, cleanPath), fileInfo.Mode()) + } + destPath := filepath.Join(destDir, cleanPath) // Create parent directories diff --git a/pkg/download/extract_7z.go b/pkg/download/extract_7z.go index 9f8365e5..b8886034 100644 --- a/pkg/download/extract_7z.go +++ b/pkg/download/extract_7z.go @@ -4,6 +4,7 @@ import ( "io" "os" "path/filepath" + "strings" "github.com/bodgit/sevenzip" ) @@ -43,7 +44,11 @@ func extractSevenZipMultiPart(firstPartPath string, destDir string, password str // Extract files with progress tracking extractedFiles := 0 for _, f := range reader.File { - destPath := filepath.Join(destDir, f.Name) + cleanName := filepath.Clean(f.Name) + if strings.HasPrefix(cleanName, "..") || filepath.IsAbs(cleanName) { + continue + } + destPath := filepath.Join(destDir, cleanName) if f.FileInfo().IsDir() { if err := os.MkdirAll(destPath, f.Mode()); err != nil { @@ -52,7 +57,6 @@ func extractSevenZipMultiPart(firstPartPath string, destDir string, password str continue } - // Ensure parent directory exists if err := os.MkdirAll(filepath.Dir(destPath), 0755); err != nil { return err }