From c5dda0ffbae8c3e2028c24f632971243595ae00c Mon Sep 17 00:00:00 2001 From: mmetc <92726601+mmetc@users.noreply.github.com> Date: Wed, 2 Mar 2022 11:30:04 +0100 Subject: [PATCH] fix: deny copy folder to itself or subpath (#1299) --- pkg/cstest/utils.go | 33 ++++++++++++++++++++++++++++++--- pkg/cstest/utils_test.go | 18 ++++++++++++++++++ 2 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 pkg/cstest/utils_test.go diff --git a/pkg/cstest/utils.go b/pkg/cstest/utils.go index b6859f30d..ea44820d9 100644 --- a/pkg/cstest/utils.go +++ b/pkg/cstest/utils.go @@ -4,6 +4,7 @@ import ( "fmt" "io/ioutil" "os" + "path/filepath" "testing" "github.com/stretchr/testify/assert" @@ -22,10 +23,36 @@ func Copy(sourceFile string, destinationFile string) error { return nil } -func CopyDir(src string, dest string) error { +// checkPathNotContained returns an error if 'subpath' is inside 'path' +func checkPathNotContained(path string, subpath string) error { + absPath, err := filepath.Abs(path) + if err != nil { + return err + } - if dest[:len(src)] == src { - return fmt.Errorf("Cannot copy a folder into the folder itself!") + absSubPath, err := filepath.Abs(subpath) + if err != nil { + return err + } + + current := absSubPath + for { + if current == absPath { + return fmt.Errorf("cannot copy a folder onto itself") + } + up := filepath.Dir(current) + if current == up { + break + } + current = up + } + return nil +} + +func CopyDir(src string, dest string) error { + err := checkPathNotContained(src, dest) + if err != nil { + return err } f, err := os.Open(src) diff --git a/pkg/cstest/utils_test.go b/pkg/cstest/utils_test.go new file mode 100644 index 000000000..c91697251 --- /dev/null +++ b/pkg/cstest/utils_test.go @@ -0,0 +1,18 @@ +package cstest + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestCheckPathNotContained(t *testing.T) { + assert.Nil(t, checkPathNotContained("/foo", "/bar")) + assert.Nil(t, checkPathNotContained("/foo/bar", "/foo")) + assert.Nil(t, checkPathNotContained("/foo/bar", "/")) + assert.Nil(t, checkPathNotContained("/path/to/somewhere", "/path/to/somewhere-else")) + assert.Nil(t, checkPathNotContained("~/.local/path/to/somewhere", "~/.local/path/to/somewhere-else")) + assert.NotNil(t, checkPathNotContained("/foo", "/foo/bar")) + assert.NotNil(t, checkPathNotContained("/", "/foo")) + assert.NotNil(t, checkPathNotContained("/", "/foo/bar/baz")) +}