From 0a828eec2c659d087450057d361ce689735baf4f Mon Sep 17 00:00:00 2001 From: Petar Maymounkov Date: Wed, 4 Aug 2021 14:34:26 -0400 Subject: [PATCH 1/4] allow .. in file and directory names --- extractor.go | 4 ++-- extractor_test.go | 4 ++-- sanitize.go | 3 +++ sanitize_windows.go | 3 +++ 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/extractor.go b/extractor.go index 4eb4796..20c404a 100644 --- a/extractor.go +++ b/extractor.go @@ -158,7 +158,7 @@ func (te *Extractor) Extract(reader io.Reader) error { // Checks if the relative path matches or exceeds the root // We check for matching because the outputPath function strips the original root rel, err := fp.Rel(rootOutputPath, outputPath) - if err != nil || rel == "." || strings.Contains(rel, "..") { + if err != nil || rel == "." { return errInvalidRootMultipleRoots } @@ -211,7 +211,7 @@ func getRelativePath(rootName, tarPath string) (string, error) { return tarPath[len(rootName)+1:], nil } -// outputPath returns the path at which to place the relativeTarPath. Assumes the path is cleaned. +// outputPath returns the directory path at which to place the file relativeTarPath. Assumes relativeTarPath is cleaned. func (te *Extractor) outputPath(basePlatformPath, relativeTarPath string) (string, error) { elems := strings.Split(relativeTarPath, "/") diff --git a/extractor_test.go b/extractor_test.go index 4dc3450..1452bab 100644 --- a/extractor_test.go +++ b/extractor_test.go @@ -45,7 +45,7 @@ func init() { } func TestSingleFile(t *testing.T) { - fileName := "file" + fileName := "file.." fileData := "file data" testTarExtraction(t, nil, []tarEntry{ @@ -64,7 +64,7 @@ func TestSingleFile(t *testing.T) { } func TestSingleDirectory(t *testing.T) { - dirName := "dir" + dirName := "dir.." testTarExtraction(t, nil, []tarEntry{ &dirTarEntry{dirName}, diff --git a/sanitize.go b/sanitize.go index a712737..628e280 100644 --- a/sanitize.go +++ b/sanitize.go @@ -20,6 +20,9 @@ func validatePlatformPath(platformPath string) error { } func validatePathComponent(c string) error { + if c == ".." { + return fmt.Errorf("invalid platform path: path component cannot be '..'") + } if strings.Contains(c, "\x00") { return fmt.Errorf("invalid platform path: path components cannot contain null: %q", c) } diff --git a/sanitize_windows.go b/sanitize_windows.go index a659863..b313d6e 100644 --- a/sanitize_windows.go +++ b/sanitize_windows.go @@ -38,6 +38,9 @@ func validatePathComponent(c string) error { return fmt.Errorf("invalid platform path: path components cannot end with ' ' : %q", c) } + if c == ".." { + return fmt.Errorf("invalid platform path: path component cannot be '..'") + } // error on reserved characters if strings.ContainsAny(c, reservedCharsStr) { return fmt.Errorf("invalid platform path: path components cannot contain any of %s : %q", reservedCharsStr, c) From 654d9752b787b492094c247849924608032d0a88 Mon Sep 17 00:00:00 2001 From: Petar Maymounkov Date: Wed, 4 Aug 2021 14:54:47 -0400 Subject: [PATCH 2/4] fix test to pass on windows --- extractor_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extractor_test.go b/extractor_test.go index 1452bab..5208591 100644 --- a/extractor_test.go +++ b/extractor_test.go @@ -45,7 +45,7 @@ func init() { } func TestSingleFile(t *testing.T) { - fileName := "file.." + fileName := "file..ext" fileData := "file data" testTarExtraction(t, nil, []tarEntry{ @@ -64,7 +64,7 @@ func TestSingleFile(t *testing.T) { } func TestSingleDirectory(t *testing.T) { - dirName := "dir.." + dirName := "dir..sfx" testTarExtraction(t, nil, []tarEntry{ &dirTarEntry{dirName}, From 1e861df303c6dfa3b295a956f32a3243ba9038e3 Mon Sep 17 00:00:00 2001 From: Petar Maymounkov Date: Thu, 5 Aug 2021 07:32:00 -0400 Subject: [PATCH 3/4] check that relative path does not contain .. --- extractor.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/extractor.go b/extractor.go index 20c404a..84d6b7a 100644 --- a/extractor.go +++ b/extractor.go @@ -161,6 +161,11 @@ func (te *Extractor) Extract(reader io.Reader) error { if err != nil || rel == "." { return errInvalidRootMultipleRoots } + for _, e := range strings.Split(rel, "/") { + if e == ".." { + return fmt.Errorf("relative path contains '..'") + } + } switch header.Typeflag { case tar.TypeDir: From 98588cc6852143d066092288e7e93aa1512cd30d Mon Sep 17 00:00:00 2001 From: Petar Maymounkov Date: Thu, 5 Aug 2021 15:53:25 -0400 Subject: [PATCH 4/4] update --- extractor.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extractor.go b/extractor.go index 84d6b7a..70327f4 100644 --- a/extractor.go +++ b/extractor.go @@ -161,7 +161,7 @@ func (te *Extractor) Extract(reader io.Reader) error { if err != nil || rel == "." { return errInvalidRootMultipleRoots } - for _, e := range strings.Split(rel, "/") { + for _, e := range strings.Split(fp.ToSlash(rel), "/") { if e == ".." { return fmt.Errorf("relative path contains '..'") }