From f869a0a67098e92d24ddd913e188b32404fa72c9 Mon Sep 17 00:00:00 2001 From: dudaodong Date: Wed, 16 Nov 2022 16:04:38 +0800 Subject: [PATCH] fix: issue#62: fix ZipSlip bug --- fileutil/file.go | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/fileutil/file.go b/fileutil/file.go index 743bbae..ef77c62 100644 --- a/fileutil/file.go +++ b/fileutil/file.go @@ -214,7 +214,6 @@ func Zip(fpath string, destPath string) error { // UnZip unzip the file and save it to destPath func UnZip(zipFile string, destPath string) error { - destPath = filepath.Clean(destPath) + string(os.PathSeparator) zipReader, err := zip.OpenReader(zipFile) if err != nil { @@ -226,8 +225,9 @@ func UnZip(zipFile string, destPath string) error { path := filepath.Join(destPath, f.Name) //issue#62: fix ZipSlip bug - if !strings.HasPrefix(path, destPath) { - return fmt.Errorf("%s: illegal file path", path) + path, err := safeFilepathJoin(destPath, f.Name) + if err != nil { + return err } if f.FileInfo().IsDir() { @@ -258,6 +258,17 @@ func UnZip(zipFile string, destPath string) error { return nil } +func safeFilepathJoin(path1, path2 string) (string, error) { + relPath, err := filepath.Rel(".", path2) + if err != nil || strings.HasPrefix(relPath, "..") { + return "", fmt.Errorf("(zipslip) filepath is unsafe %q: %v", path2, err) + } + if path1 == "" { + path1 = "." + } + return filepath.Join(path1, filepath.Join("/", relPath)), nil +} + // IsLink checks if a file is symbol link or not func IsLink(path string) bool { fi, err := os.Lstat(path)